|
|
@ -17,32 +17,37 @@ class MMU:
|
|
|
|
The MemoryManagementUnit (handles loading binaries, and reading/writing data)
|
|
|
|
The MemoryManagementUnit (handles loading binaries, and reading/writing data)
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
max_size = 0xFFFFFFFF
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
The maximum size of the memory in bytes
|
|
|
|
The maximum size of the memory in bytes
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
max_size = 0xFFFFFFFF
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sections: List[LoadedMemorySection]
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
A list of all loaded memory sections
|
|
|
|
A list of all loaded memory sections
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
sections: List[LoadedMemorySection]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
binaries: List[LoadedExecutable]
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
A list of all loaded executables
|
|
|
|
A list of all loaded executables
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
binaries: List[LoadedExecutable]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
last_bin: Optional[LoadedExecutable] = None
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
The last loaded executable (the next executable is inserted directly after this one)
|
|
|
|
The last loaded executable (the next executable is inserted directly after this one)
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
last_bin: Optional[LoadedExecutable] = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global_symbols: Dict[str, int]
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
The global symbol table
|
|
|
|
The global symbol table
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
global_symbols: Dict[str, int]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, conf: RunConfig):
|
|
|
|
def __init__(self, conf: RunConfig):
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
Create a new MMU, respeccting the active RunConfiguration
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:param conf: The config to respect
|
|
|
|
|
|
|
|
"""
|
|
|
|
self.sections = list()
|
|
|
|
self.sections = list()
|
|
|
|
self.binaries = list()
|
|
|
|
self.binaries = list()
|
|
|
|
self.last_bin = None
|
|
|
|
self.last_bin = None
|
|
|
@ -52,6 +57,7 @@ class MMU:
|
|
|
|
def load_bin(self, bin: Executable) -> LoadedExecutable:
|
|
|
|
def load_bin(self, bin: Executable) -> LoadedExecutable:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Load an executable into memory
|
|
|
|
Load an executable into memory
|
|
|
|
|
|
|
|
|
|
|
|
:param bin: the executable to load
|
|
|
|
:param bin: the executable to load
|
|
|
|
:return: A LoadedExecutable
|
|
|
|
:return: A LoadedExecutable
|
|
|
|
:raises OutOfMemoryException: When all memory is used
|
|
|
|
:raises OutOfMemoryException: When all memory is used
|
|
|
@ -88,6 +94,7 @@ class MMU:
|
|
|
|
def get_sec_containing(self, addr: int) -> Optional[LoadedMemorySection]:
|
|
|
|
def get_sec_containing(self, addr: int) -> Optional[LoadedMemorySection]:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Returns the section that contains the address addr
|
|
|
|
Returns the section that contains the address addr
|
|
|
|
|
|
|
|
|
|
|
|
:param addr: the Address to look for
|
|
|
|
:param addr: the Address to look for
|
|
|
|
:return: The LoadedMemorySection or None
|
|
|
|
:return: The LoadedMemorySection or None
|
|
|
|
"""
|
|
|
|
"""
|
|
|
@ -99,6 +106,7 @@ class MMU:
|
|
|
|
def read_ins(self, addr: int) -> LoadedInstruction:
|
|
|
|
def read_ins(self, addr: int) -> LoadedInstruction:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Read a single instruction located at addr
|
|
|
|
Read a single instruction located at addr
|
|
|
|
|
|
|
|
|
|
|
|
:param addr: The location
|
|
|
|
:param addr: The location
|
|
|
|
:return: The Instruction
|
|
|
|
:return: The Instruction
|
|
|
|
"""
|
|
|
|
"""
|
|
|
@ -108,6 +116,7 @@ class MMU:
|
|
|
|
def read(self, addr: int, size: int) -> bytearray:
|
|
|
|
def read(self, addr: int, size: int) -> bytearray:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Read size bytes of memory at addr
|
|
|
|
Read size bytes of memory at addr
|
|
|
|
|
|
|
|
|
|
|
|
:param addr: The addres at which to start reading
|
|
|
|
:param addr: The addres at which to start reading
|
|
|
|
:param size: The number of bytes to read
|
|
|
|
:param size: The number of bytes to read
|
|
|
|
:return: The bytearray at addr
|
|
|
|
:return: The bytearray at addr
|
|
|
@ -118,6 +127,7 @@ class MMU:
|
|
|
|
def write(self, addr: int, size: int, data):
|
|
|
|
def write(self, addr: int, size: int, data):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Write bytes into memory
|
|
|
|
Write bytes into memory
|
|
|
|
|
|
|
|
|
|
|
|
:param addr: The address at which to write
|
|
|
|
:param addr: The address at which to write
|
|
|
|
:param size: The number of bytes to write
|
|
|
|
:param size: The number of bytes to write
|
|
|
|
:param data: The bytearray to write (only first size bytes are written)
|
|
|
|
:param data: The bytearray to write (only first size bytes are written)
|
|
|
@ -138,9 +148,10 @@ class MMU:
|
|
|
|
return
|
|
|
|
return
|
|
|
|
sec.dump(addr, *args, **kwargs)
|
|
|
|
sec.dump(addr, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
def symbol(self, symb:str):
|
|
|
|
def symbol(self, symb: str):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Look up the symbol symb in all local symbol tables (and the global one)
|
|
|
|
Look up the symbol symb in all local symbol tables (and the global one)
|
|
|
|
|
|
|
|
|
|
|
|
:param symb: The symbol name to look up
|
|
|
|
:param symb: The symbol name to look up
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
print(FMT_MEM + "[MMU] Lookup for symbol {}:".format(symb) + FMT_NONE)
|
|
|
|
print(FMT_MEM + "[MMU] Lookup for symbol {}:".format(symb) + FMT_NONE)
|
|
|
@ -153,4 +164,4 @@ class MMU:
|
|
|
|
def __repr__(self):
|
|
|
|
def __repr__(self):
|
|
|
|
return "MMU(\n\t{}\n)".format(
|
|
|
|
return "MMU(\n\t{}\n)".format(
|
|
|
|
"\n\t".join(repr(x) for x in self.sections)
|
|
|
|
"\n\t".join(repr(x) for x in self.sections)
|
|
|
|
)
|
|
|
|
)
|
|
|
|