more work on syscalls
parent
a69cc7d346
commit
a483db65c7
@ -0,0 +1,48 @@
|
||||
from dataclasses import dataclass
|
||||
from .Registers import Registers
|
||||
from .Exceptions import InvalidSyscallException
|
||||
|
||||
import typing
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from . import CPU
|
||||
|
||||
SYSCALLS = {
|
||||
63: 'read',
|
||||
64: 'write',
|
||||
93: 'exit'
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Syscall:
|
||||
id: int
|
||||
registers: Registers
|
||||
cpu: 'CPU'
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return SYSCALLS.get(self.id, "unknown")
|
||||
|
||||
def __repr__(self):
|
||||
return "Syscall(id={}, name={})".format(
|
||||
self.id, self.name
|
||||
)
|
||||
|
||||
|
||||
class SyscallInterface:
|
||||
def handle_syscall(self, scall: Syscall):
|
||||
if getattr(self, scall.name):
|
||||
getattr(self, scall.name)(scall)
|
||||
else:
|
||||
raise InvalidSyscallException(scall)
|
||||
|
||||
def read(self, scall: Syscall):
|
||||
pass
|
||||
|
||||
def write(self, scall: Syscall):
|
||||
pass
|
||||
|
||||
def exit(self, scall: Syscall):
|
||||
scall.cpu.exit = True
|
||||
scall.cpu.exit_code = scall.registers.get('a0')
|
@ -0,0 +1,52 @@
|
||||
if __name__ == '__main__':
|
||||
from . import *
|
||||
from .helpers import *
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='RISC-V Userspace parser and emulator')
|
||||
parser.add_argument('file', metavar='file.asm', type=str, help='The assembly file to interpret and run')
|
||||
|
||||
# RunConfig parameters
|
||||
parser.add_argument('color', type=bool, help='Colored output', default=True)
|
||||
parser.add_argument('default_stack_size', type=int, help='Default stack size of loaded programs', default=None,
|
||||
metavar='default-stack-size')
|
||||
parser.add_argument('debug_instruction', type=bool, default=True, metavar='debug-instruction',
|
||||
help='Adds the dbg instruction, which launches an interactive debuggin session, smilar to '
|
||||
'a breakpoint.')
|
||||
|
||||
parser.add_argument('print_tokens', metavar='print-tokens', type=bool, help='Print tokens after tokenization',
|
||||
default=False)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
cfg = RunConfig(
|
||||
color=args.color,
|
||||
preffered_stack_size=args.default_stack_size,
|
||||
debug_instruction=args.debug_instruction
|
||||
)
|
||||
|
||||
if cfg.color:
|
||||
FMT_PRINT = FMT_BOLD + FMT_MAGENTA
|
||||
else:
|
||||
FMT_NONE = ""
|
||||
FMT_PRINT = ""
|
||||
|
||||
with open(args.file, 'r') as f:
|
||||
asm = f.read()
|
||||
|
||||
tk = RiscVTokenizer(RiscVInput(asm))
|
||||
tk.tokenize()
|
||||
|
||||
if args.print_tokens:
|
||||
print(FMT_PRINT + "Tokens:" + FMT_NONE)
|
||||
for token in tk.tokens:
|
||||
print(token)
|
||||
|
||||
executable = ExecutableParser(tk).parse().get_execuable()
|
||||
|
||||
print(FMT_PRINT + "Executable:" + FMT_NONE, executable)
|
||||
|
||||
cpu = CPU(cfg)
|
||||
le = cpu.load(executable)
|
||||
cpu.run_loaded(le)
|
||||
|
Loading…
Reference in New Issue