various small bugfixes

assembly-parser-rework
Anton Lydike 3 years ago
parent 881f4004ed
commit 4f1c73df9e

@ -88,6 +88,8 @@ class UserModeCPU(CPU):
while not self.halted: while not self.halted:
self.step(verbose) self.step(verbose)
print(FMT_CPU + "[CPU] Program exited with code {}".format(self.exit_code) + FMT_NONE)
def setup_stack(self, stack_size=1024 * 4) -> bool: def setup_stack(self, stack_size=1024 * 4) -> bool:
""" """
Create program stack and populate stack pointer Create program stack and populate stack pointer

@ -234,10 +234,10 @@ class MMU:
"\n\t".join(repr(x) for x in self.programs) "\n\t".join(repr(x) for x in self.programs)
) )
def context_for(self, addr: T_AbsoluteAddress) -> Optional[InstructionContext]: def context_for(self, addr: T_AbsoluteAddress) -> InstructionContext:
sec = self.get_sec_containing(addr) sec = self.get_sec_containing(addr)
if sec is not None: if sec is not None:
return sec.context return sec.context
return None return InstructionContext()

@ -5,6 +5,7 @@ SPDX-License-Identifier: MIT
This file holds the logic for starting the emulator from the CLI This file holds the logic for starting the emulator from the CLI
""" """
from riscemu import RiscemuBaseException
from riscemu.CPU import UserModeCPU from riscemu.CPU import UserModeCPU
if __name__ == '__main__': if __name__ == '__main__':
@ -114,6 +115,7 @@ if __name__ == '__main__':
# launch the last loaded program # launch the last loaded program
cpu.launch(cpu.mmu.programs[-1], verbose=cfg.verbosity > 1) cpu.launch(cpu.mmu.programs[-1], verbose=cfg.verbosity > 1)
except RiscemuBaseException as e: except RiscemuBaseException as e:
print("Error: {}".format(e.message())) print("Error: {}".format(e.message()))
e.print_stacktrace() e.print_stacktrace()

@ -175,8 +175,9 @@ class AssemblerDirectives:
if content is None: if content is None:
content = bytearray(size) content = bytearray(size)
if isinstance(context, int): if isinstance(content, int):
content = int_to_bytes(content, size, unsigned) content = int_to_bytes(content, size, unsigned)
context.section.data += content context.section.data += content
@classmethod @classmethod

@ -11,6 +11,7 @@ from .helpers import *
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
from riscemu import CPU, Registers from riscemu import CPU, Registers
HIST_FILE = os.path.join(os.path.expanduser('~'), '.riscemu_history')
def launch_debug_session(cpu: 'CPU', prompt=""): def launch_debug_session(cpu: 'CPU', prompt=""):
@ -78,8 +79,8 @@ def launch_debug_session(cpu: 'CPU', prompt=""):
# add tab completion # add tab completion
readline.set_completer(rlcompleter.Completer(sess_vars).complete) readline.set_completer(rlcompleter.Completer(sess_vars).complete)
readline.parse_and_bind("tab: complete") readline.parse_and_bind("tab: complete")
if os.path.exists('~/.riscemu_history'): if os.path.exists(HIST_FILE):
readline.read_history_file('~/.riscemu_history') readline.read_history_file(HIST_FILE)
relaunch_debugger = False relaunch_debugger = False
@ -90,5 +91,5 @@ def launch_debug_session(cpu: 'CPU', prompt=""):
) )
finally: finally:
cpu.debugger_active = False cpu.debugger_active = False
readline.write_history_file('~/.riscemu_history') readline.write_history_file(HIST_FILE)

@ -46,7 +46,7 @@ def int_from_bytes(bytes, unsigned=False) -> int:
if unsigned: if unsigned:
return num return num
return to_signed(num) return to_signed(num, len(bytes))
def to_unsigned(num: int, bytes=4) -> int: def to_unsigned(num: int, bytes=4) -> int:

@ -31,7 +31,7 @@ def parse_label(token: Token, args: Tuple[str], context: ParseContext):
else: else:
if name in context.context.labels: if name in context.context.labels:
print(FMT_PARSE + 'Warn: Symbol {} defined twice!'.format(name)) print(FMT_PARSE + 'Warn: Symbol {} defined twice!'.format(name))
context.context.labels[name] = context.section.current_address() context.add_label(name, context.section.current_address(), is_relative=True)
PARSERS: Dict[TokenType, Callable[[Token, Tuple[str], ParseContext], None]] = { PARSERS: Dict[TokenType, Callable[[Token, Tuple[str], ParseContext], None]] = {
@ -53,7 +53,6 @@ def parse_tokens(name: str, tokens_iter: Iterable[Token]) -> Program:
for token, args in composite_tokenizer(Peekable[Token](tokens_iter)): for token, args in composite_tokenizer(Peekable[Token](tokens_iter)):
if token.type not in PARSERS: if token.type not in PARSERS:
raise ParseException("Unexpected token type: {}, {}".format(token, args)) raise ParseException("Unexpected token type: {}, {}".format(token, args))
print('{}: {}'.format(token, args))
PARSERS[token.type](token, args, context) PARSERS[token.type](token, args, context)
return context.finalize() return context.finalize()
@ -74,8 +73,6 @@ def composite_tokenizer(tokens_iter: Iterable[Token]) -> Iterable[Tuple[Token, T
token = next(tokens) token = next(tokens)
if token.type in (TokenType.PSEUDO_OP, TokenType.LABEL, TokenType.INSTRUCTION_NAME): if token.type in (TokenType.PSEUDO_OP, TokenType.LABEL, TokenType.INSTRUCTION_NAME):
yield token, tuple(take_arguments(tokens)) yield token, tuple(take_arguments(tokens))
else:
print("skipped {}".format(token))
def take_arguments(tokens: Peekable[Token]) -> Iterable[str]: def take_arguments(tokens: Peekable[Token]) -> Iterable[str]:

@ -24,7 +24,7 @@ class PrivMMU(MMU):
# calc start end end of "free" space # calc start end end of "free" space
prev_sec_end = 0 if sec_before is None else sec_before.end prev_sec_end = 0 if sec_before is None else sec_before.end
next_sec_start = 0x7FFFFFFF if sec_after is None else sec_before.base next_sec_start = 0x7FFFFFFF if sec_after is None else sec_after.base
# start at the end of the prev section, or current address - 0xFFFF (aligned to 16 byte boundary) # start at the end of the prev section, or current address - 0xFFFF (aligned to 16 byte boundary)
start = max(prev_sec_end, align_addr(addr - 0xFFFF, 16)) start = max(prev_sec_end, align_addr(addr - 0xFFFF, 16))

@ -258,11 +258,10 @@ class Program:
@property @property
def entrypoint(self): def entrypoint(self):
base = 0 if self.base is None else self.base
if '_start' in self.context.labels: if '_start' in self.context.labels:
return base + self.context.labels.get('_start') return self.context.labels.get('_start')
if 'main' in self.context.labels: if 'main' in self.context.labels:
return base + self.context.labels.get('main') return self.context.labels.get('main')
for sec in self.sections: for sec in self.sections:
if get_section_base_name(sec.name) == '.text' and sec.flags.executable: if get_section_base_name(sec.name) == '.text' and sec.flags.executable:
return sec.base return sec.base

Loading…
Cancel
Save