implemented mmu.allocate_region and reworked how the stack works

float_support
Anton Lydike 4 years ago
parent bc8c061c6d
commit 242af5c7a3

@ -10,7 +10,7 @@ import sys
from typing import Tuple, List, Dict, Callable, Type
from .Tokenizer import RiscVTokenizer
from .Executable import MemoryFlags
from .Syscall import SyscallInterface, get_syscall_symbols
from .Exceptions import RiscemuBaseException, LaunchDebuggerException
from .MMU import MMU
@ -85,6 +85,12 @@ class CPU:
Run a loaded executable
"""
self.pc = le.run_ptr
if self.conf.stack_size > 0:
stack = self.mmu.allocate_section("stack", self.conf.stack_size, MemoryFlags(False, False))
self.regs.set('sp', stack.base + stack.size)
print(FMT_CPU + '[CPU] Allocated {} bytes of stack'.format(stack.size) + FMT_NONE)
print(FMT_CPU + '[CPU] Started running from 0x{:08X} ({})'.format(le.run_ptr, le.name) + FMT_NONE)
self.__run()

@ -10,7 +10,7 @@ from typing import Optional
@dataclass(frozen=True, init=True)
class RunConfig:
preffered_stack_size: Optional[int] = None
stack_size: int = 0 # 8 * 1024 * 1024 * 8 # for 8MB stack
include_scall_symbols: bool = True
add_accept_imm: bool = False
# debugging

@ -90,12 +90,28 @@ class OutOfMemoryException(RiscemuBaseException):
self.action = action
def message(self):
return + FMT_MEM + '{}(Ran out of memory during {})'.format(
return FMT_MEM + '{}(Ran out of memory during {})'.format(
self.__class__.__name__,
self.action
) + FMT_NONE
class InvalidAllocationException(RiscemuBaseException):
def __init__(self, msg, name, size, flags):
self.msg = msg
self.name = name
self.size = size
self.flags = flags
def message(self):
return FMT_MEM + '{}[{}](name={}, size={}, flags={})'.format(
self.__class__.__name__,
self.msg,
self.name,
self.size,
self.flags
)
# CPU Exceptions

@ -7,7 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause
from .Config import RunConfig
from .Executable import Executable, LoadedExecutable, LoadedMemorySection, LoadedInstruction, MemoryFlags
from .helpers import align_addr
from .Exceptions import OutOfMemoryException
from .Exceptions import OutOfMemoryException, InvalidAllocationException
from .colors import *
from typing import Dict, List, Tuple, Optional
@ -22,6 +22,11 @@ class MMU:
The maximum size of the memory in bytes
"""
max_alloc_size = 8 * 1024 * 1024 * 64
"""
No single allocation can be bigger than 64 MB
"""
sections: List[LoadedMemorySection]
"""
A list of all loaded memory sections
@ -84,6 +89,32 @@ class MMU:
return loaded_bin
def allocate_section(self, name: str, req_size: int, flag: MemoryFlags):
"""
Used to allocate a memory region (data only). Use `load_bin` if you want to load a binary, this is used for
stack and maybe malloc in the future.
:param name: Name of the section to allocate
:param req_size: The requested size
:param flag: The flags protecting this memory section
:return: The LoadedMemorySection
"""
if flag.executable:
raise InvalidAllocationException('cannot allocate executable section', name, req_size, flag)
if req_size < 0:
raise InvalidAllocationException('Invalid size request', name, req_size, flag)
if req_size > self.max_alloc_size:
raise InvalidAllocationException('Cannot allocate more than {} bytes at a time'.format(self.max_alloc_size), name, req_size, flag)
base = align_addr(self.first_free_addr)
size = align_addr(req_size)
sec = LoadedMemorySection(name, base, size, bytearray(size), flag, "<runtime>")
self.sections.append(sec)
self.first_free_addr = base + size
return sec
def get_sec_containing(self, addr: int) -> Optional[LoadedMemorySection]:
"""
Returns the section that contains the address addr

@ -62,13 +62,13 @@ if __name__ == '__main__':
help="Instruction sets to load, available are: {}. All are enabled by default"
.format(", ".join(all_ins_names)), keys={k: True for k in all_ins_names}, omit_empty=True)
parser.add_argument('--default_stack_size', type=int, help='Default stack size of loaded programs', default=None,
metavar='default-stack-size', nargs='?')
parser.add_argument('--stack_size', type=int, help='Stack size of loaded programs, defaults to 8MB', nargs='?')
args = parser.parse_args()
cfg = RunConfig(
preffered_stack_size=args.default_stack_size,
# create a RunConfig from the cli args
cfg_dict = dict(
stack_size=args.stack_size,
debug_instruction=not args.options['disable_debug'],
include_scall_symbols=not args.options['no_syscall_symbols'],
debug_on_exception=not args.options['fail_on_ex'],
@ -76,6 +76,11 @@ if __name__ == '__main__':
scall_fs=args.syscall_opts['fs_access'],
scall_input=not args.syscall_opts['disable_input']
)
for k, v in dict(cfg_dict).items():
if v is None:
del cfg_dict[k]
cfg = RunConfig(**cfg_dict)
if not hasattr(args, 'ins'):
setattr(args, 'ins', {k: True for k in all_ins_names})

Loading…
Cancel
Save