removed stack pref pseudo-op in preperation for real stack impl
This commit is contained in:
parent
a52506a17f
commit
bc8c061c6d
@ -35,10 +35,3 @@ Currently only these three sections are supported:
|
||||
* `data` read-write data (non-executable)
|
||||
* `rodata` read-only data (non-executable)
|
||||
* `text` executable data (read-only)
|
||||
|
||||
|
||||
## Allocating stack
|
||||
another pseudo-op is recognized: `.stack <len>`. This marks the executable as requesting at least `<len>` bytes of stack.
|
||||
If the loader respects this wish, the sp is initialized pointing to the end of the stack.
|
||||
|
||||
|
@ -85,9 +85,6 @@ class CPU:
|
||||
Run a loaded executable
|
||||
"""
|
||||
self.pc = le.run_ptr
|
||||
sp, hp = le.stack_heap
|
||||
self.regs.set('sp', sp)
|
||||
self.regs.set('a0', hp) # set a0 to point to the heap
|
||||
print(FMT_CPU + '[CPU] Started running from 0x{:08X} ({})'.format(le.run_ptr, le.name) + FMT_NONE)
|
||||
self.__run()
|
||||
|
||||
|
@ -75,16 +75,14 @@ class Executable:
|
||||
run_ptr: Tuple[str, int]
|
||||
sections: Dict[str, MemorySection]
|
||||
symbols: Dict[str, Tuple[str, int]]
|
||||
stack_pref: Optional[int]
|
||||
exported_symbols: List[str]
|
||||
name: str
|
||||
|
||||
def __repr__(self):
|
||||
return "{}(sections = {}, symbols = {}, stack = {}, run_ptr = {}, globals={})".format(
|
||||
return "{}(sections = {}, symbols = {}, run_ptr = {}, globals={})".format(
|
||||
self.__class__.__name__,
|
||||
" ".join(self.sections.keys()),
|
||||
" ".join(self.symbols.keys()),
|
||||
self.stack_pref,
|
||||
self.run_ptr,
|
||||
",".join(self.exported_symbols)
|
||||
)
|
||||
@ -257,7 +255,6 @@ class LoadedExecutable:
|
||||
sections: List[LoadedMemorySection]
|
||||
symbols: Dict[str, int]
|
||||
run_ptr: int
|
||||
stack_heap: Tuple[int, int] # pointers to stack and heap, are nullptr if no stack/heap is available
|
||||
exported_symbols: Dict[str, int]
|
||||
global_symbol_table: Dict[str, int]
|
||||
|
||||
@ -284,20 +281,6 @@ class LoadedExecutable:
|
||||
self.sections_by_name[loaded_sec.name] = loaded_sec
|
||||
curr = align_addr(loaded_sec.size + curr)
|
||||
|
||||
# stack/heap if wanted
|
||||
if exe.stack_pref is not None:
|
||||
self.sections.append(LoadedMemorySection(
|
||||
'stack',
|
||||
curr,
|
||||
exe.stack_pref,
|
||||
bytearray(exe.stack_pref),
|
||||
MemoryFlags(read_only=False, executable=False),
|
||||
self.name
|
||||
))
|
||||
self.stack_heap = (curr, curr + exe.stack_pref)
|
||||
else:
|
||||
self.stack_heap = (0, 0)
|
||||
|
||||
for name, (sec_name, offset) in exe.symbols.items():
|
||||
if sec_name == '_static_':
|
||||
self.symbols[name] = offset
|
||||
|
@ -28,7 +28,6 @@ class ExecutableParser:
|
||||
self.tokenizer = tokenizer
|
||||
self.active_section: Optional[str] = None
|
||||
self.implicit_sections = False
|
||||
self.stack_pref: Optional[int] = None
|
||||
self.globals: List[str] = list()
|
||||
|
||||
def parse(self) -> Executable:
|
||||
@ -52,7 +51,7 @@ class ExecutableParser:
|
||||
start_ptr = self.symbols['_start']
|
||||
elif 'main' in self.symbols:
|
||||
start_ptr = self.symbols['main']
|
||||
return Executable(start_ptr, self.sections, self.symbols, self.stack_pref, self.globals, self.tokenizer.name)
|
||||
return Executable(start_ptr, self.sections, self.symbols, self.globals, self.tokenizer.name)
|
||||
|
||||
def parse_instruction(self, ins: 'RiscVInstructionToken') -> None:
|
||||
"""
|
||||
@ -152,15 +151,6 @@ class ExecutableParser:
|
||||
str = op.args[0][1:-1].encode('ascii').decode('unicode_escape')
|
||||
self._curr_sec().add(bytearray(str + '\0', 'ascii'))
|
||||
|
||||
def op_stack(self, op: 'RiscVPseudoOpToken'):
|
||||
"""
|
||||
handles a .stack token. Sets the stack size preferences
|
||||
:param op: The token
|
||||
"""
|
||||
ASSERT_LEN(op.args, 1)
|
||||
size = parse_numeric_argument(op.args[0])
|
||||
self.stack_pref = size
|
||||
|
||||
def op_global(self, op: 'RiscVPseudoOpToken'):
|
||||
"""
|
||||
handles a .global token. Marks the token as global
|
||||
@ -192,7 +182,6 @@ class ExecutableParser:
|
||||
val = parse_numeric_argument(op.args[0])
|
||||
self._curr_sec().add(int_to_bytes(val, 4))
|
||||
|
||||
|
||||
## Section handler code
|
||||
def _set_sec(self, name: str, flags: MemoryFlags, cls=MemorySection):
|
||||
if name not in self.sections:
|
||||
|
@ -5,7 +5,7 @@ SPDX-License-Identifier: BSD-2-Clause
|
||||
"""
|
||||
|
||||
from .Config import RunConfig
|
||||
from .Executable import Executable, LoadedExecutable, LoadedMemorySection, LoadedInstruction
|
||||
from .Executable import Executable, LoadedExecutable, LoadedMemorySection, LoadedInstruction, MemoryFlags
|
||||
from .helpers import align_addr
|
||||
from .Exceptions import OutOfMemoryException
|
||||
from .colors import *
|
||||
@ -48,38 +48,31 @@ class MMU:
|
||||
|
||||
:param conf: The config to respect
|
||||
"""
|
||||
self.sections = list()
|
||||
self.binaries = list()
|
||||
self.last_bin = None
|
||||
self.conf = conf
|
||||
self.global_symbols = dict()
|
||||
self.sections: List[LoadedMemorySection] = list()
|
||||
self.binaries: List[LoadedExecutable] = list()
|
||||
self.first_free_addr: int = 0x100
|
||||
self.conf: RunConfig = conf
|
||||
self.global_symbols: Dict[str, int] = dict()
|
||||
|
||||
def load_bin(self, bin: Executable) -> LoadedExecutable:
|
||||
def load_bin(self, exe: Executable) -> LoadedExecutable:
|
||||
"""
|
||||
Load an executable into memory
|
||||
|
||||
:param bin: the executable to load
|
||||
:param exe: the executable to load
|
||||
:return: A LoadedExecutable
|
||||
:raises OutOfMemoryException: When all memory is used
|
||||
"""
|
||||
if self.last_bin is None:
|
||||
addr = 0x100 # start at 0x100 instead of 0x00
|
||||
else:
|
||||
addr = self.last_bin.size + self.last_bin.base_addr
|
||||
|
||||
# align to 8 byte word
|
||||
addr = align_addr(addr)
|
||||
addr = align_addr(self.first_free_addr)
|
||||
|
||||
# apply preferred stack size from config
|
||||
if bin.stack_pref is None:
|
||||
bin.stack_pref = self.conf.preffered_stack_size
|
||||
|
||||
loaded_bin = LoadedExecutable(bin, addr, self.global_symbols)
|
||||
loaded_bin = LoadedExecutable(exe, addr, self.global_symbols)
|
||||
|
||||
if loaded_bin.size + addr > self.max_size:
|
||||
raise OutOfMemoryException('load of executable')
|
||||
|
||||
self.binaries.append(loaded_bin)
|
||||
self.last_bin = loaded_bin
|
||||
self.first_free_addr = loaded_bin.base_addr + loaded_bin.size
|
||||
|
||||
# read sections into sec dict
|
||||
for sec in loaded_bin.sections:
|
||||
|
@ -15,7 +15,6 @@ PSEUDO_OPS = [
|
||||
'.double',
|
||||
'.extern',
|
||||
'.global',
|
||||
'.stack',
|
||||
'.align',
|
||||
'.float',
|
||||
'.kdata',
|
||||
|
@ -15,6 +15,7 @@ if __name__ == '__main__':
|
||||
|
||||
all_ins_names = list(InstructionSetDict.keys())
|
||||
|
||||
|
||||
class OptionStringAction(argparse.Action):
|
||||
def __init__(self, option_strings, dest, keys=None, omit_empty=False, **kwargs):
|
||||
if keys is None:
|
||||
@ -57,8 +58,8 @@ if __name__ == '__main__':
|
||||
parser.add_argument('--syscall-opts', '-so', action=OptionStringAction,
|
||||
keys=('fs_access', 'disable_input'))
|
||||
|
||||
parser.add_argument('--instruction-sets', '-is', action=OptionStringAction, help="Instruction sets to load, available are: {}. "
|
||||
"All are enabled by default"
|
||||
parser.add_argument('--instruction-sets', '-is', action=OptionStringAction,
|
||||
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,
|
||||
@ -76,7 +77,6 @@ if __name__ == '__main__':
|
||||
scall_input=not args.syscall_opts['disable_input']
|
||||
)
|
||||
|
||||
|
||||
if not hasattr(args, 'ins'):
|
||||
setattr(args, 'ins', {k: True for k in all_ins_names})
|
||||
|
||||
@ -99,7 +99,6 @@ if __name__ == '__main__':
|
||||
except RiscemuBaseException as e:
|
||||
print("Error while parsing: {}".format(e.message()))
|
||||
import traceback
|
||||
|
||||
traceback.print_exception(type(e), e, e.__traceback__)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user