diff --git a/riscemu/CPU.py b/riscemu/CPU.py index 8e3c395..3b9235d 100644 --- a/riscemu/CPU.py +++ b/riscemu/CPU.py @@ -88,6 +88,8 @@ class UserModeCPU(CPU): while not self.halted: 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: """ Create program stack and populate stack pointer diff --git a/riscemu/MMU.py b/riscemu/MMU.py index a91ca9b..eeb75d7 100644 --- a/riscemu/MMU.py +++ b/riscemu/MMU.py @@ -234,10 +234,10 @@ class MMU: "\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) if sec is not None: return sec.context - return None + return InstructionContext() diff --git a/riscemu/__main__.py b/riscemu/__main__.py index 82d3d1b..96ac45e 100644 --- a/riscemu/__main__.py +++ b/riscemu/__main__.py @@ -5,6 +5,7 @@ SPDX-License-Identifier: MIT This file holds the logic for starting the emulator from the CLI """ +from riscemu import RiscemuBaseException from riscemu.CPU import UserModeCPU if __name__ == '__main__': @@ -114,6 +115,7 @@ if __name__ == '__main__': # launch the last loaded program cpu.launch(cpu.mmu.programs[-1], verbose=cfg.verbosity > 1) + except RiscemuBaseException as e: print("Error: {}".format(e.message())) e.print_stacktrace() diff --git a/riscemu/assembler.py b/riscemu/assembler.py index 869b9e4..768d504 100644 --- a/riscemu/assembler.py +++ b/riscemu/assembler.py @@ -175,8 +175,9 @@ class AssemblerDirectives: if content is None: content = bytearray(size) - if isinstance(context, int): + if isinstance(content, int): content = int_to_bytes(content, size, unsigned) + context.section.data += content @classmethod diff --git a/riscemu/debug.py b/riscemu/debug.py index 0885843..fd68f7b 100644 --- a/riscemu/debug.py +++ b/riscemu/debug.py @@ -11,6 +11,7 @@ from .helpers import * if typing.TYPE_CHECKING: from riscemu import CPU, Registers +HIST_FILE = os.path.join(os.path.expanduser('~'), '.riscemu_history') def launch_debug_session(cpu: 'CPU', prompt=""): @@ -78,8 +79,8 @@ def launch_debug_session(cpu: 'CPU', prompt=""): # add tab completion readline.set_completer(rlcompleter.Completer(sess_vars).complete) readline.parse_and_bind("tab: complete") - if os.path.exists('~/.riscemu_history'): - readline.read_history_file('~/.riscemu_history') + if os.path.exists(HIST_FILE): + readline.read_history_file(HIST_FILE) relaunch_debugger = False @@ -90,5 +91,5 @@ def launch_debug_session(cpu: 'CPU', prompt=""): ) finally: cpu.debugger_active = False - readline.write_history_file('~/.riscemu_history') + readline.write_history_file(HIST_FILE) diff --git a/riscemu/helpers.py b/riscemu/helpers.py index 9c94635..3048cb1 100644 --- a/riscemu/helpers.py +++ b/riscemu/helpers.py @@ -46,7 +46,7 @@ def int_from_bytes(bytes, unsigned=False) -> int: if unsigned: return num - return to_signed(num) + return to_signed(num, len(bytes)) def to_unsigned(num: int, bytes=4) -> int: diff --git a/riscemu/parser.py b/riscemu/parser.py index 711abba..f70cfa3 100644 --- a/riscemu/parser.py +++ b/riscemu/parser.py @@ -31,7 +31,7 @@ def parse_label(token: Token, args: Tuple[str], context: ParseContext): else: if name in context.context.labels: 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]] = { @@ -53,7 +53,6 @@ def parse_tokens(name: str, tokens_iter: Iterable[Token]) -> Program: for token, args in composite_tokenizer(Peekable[Token](tokens_iter)): if token.type not in PARSERS: raise ParseException("Unexpected token type: {}, {}".format(token, args)) - print('{}: {}'.format(token, args)) PARSERS[token.type](token, args, context) return context.finalize() @@ -74,8 +73,6 @@ def composite_tokenizer(tokens_iter: Iterable[Token]) -> Iterable[Tuple[Token, T token = next(tokens) if token.type in (TokenType.PSEUDO_OP, TokenType.LABEL, TokenType.INSTRUCTION_NAME): yield token, tuple(take_arguments(tokens)) - else: - print("skipped {}".format(token)) def take_arguments(tokens: Peekable[Token]) -> Iterable[str]: diff --git a/riscemu/priv/PrivMMU.py b/riscemu/priv/PrivMMU.py index f6a86d6..1504ab2 100644 --- a/riscemu/priv/PrivMMU.py +++ b/riscemu/priv/PrivMMU.py @@ -24,7 +24,7 @@ class PrivMMU(MMU): # calc start end end of "free" space 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 = max(prev_sec_end, align_addr(addr - 0xFFFF, 16)) diff --git a/riscemu/types.py b/riscemu/types.py index f5c9989..0746d3d 100644 --- a/riscemu/types.py +++ b/riscemu/types.py @@ -258,11 +258,10 @@ class Program: @property def entrypoint(self): - base = 0 if self.base is None else self.base 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: - return base + self.context.labels.get('main') + return self.context.labels.get('main') for sec in self.sections: if get_section_base_name(sec.name) == '.text' and sec.flags.executable: return sec.base