core: refactor how launch() works in preperation for libc integration

master
Anton Lydike 1 year ago
parent 270c3e7090
commit 283bb1ae14

@ -72,7 +72,7 @@ class MMU:
return sec return sec
return None return None
def get_bin_containing(self, addr: T_AbsoluteAddress) -> Optional[Program]: def get_program_at_addr(self, addr: T_AbsoluteAddress) -> Optional[Program]:
for program in self.programs: for program in self.programs:
if program.base <= addr < program.base + program.size: if program.base <= addr < program.base + program.size:
return program return program
@ -192,7 +192,7 @@ class MMU:
if not sec: if not sec:
return "unknown at 0x{:0x}".format(address) return "unknown at 0x{:0x}".format(address)
bin = self.get_bin_containing(address) bin = self.get_program_at_addr(address)
secs = set(sec.name for sec in bin.sections) if bin else [] secs = set(sec.name for sec in bin.sections) if bin else []
elf_markers = { elf_markers = {
"__global_pointer$", "__global_pointer$",
@ -347,3 +347,13 @@ class MMU:
return sec.context return sec.context
return InstructionContext() return InstructionContext()
def find_entrypoint(self) -> int | None:
# try to find the global entrypoint
if "_start" in self.global_symbols:
return self.global_symbols["_start"]
# otherwise find a main (that's not necessarily global)
for p in self.programs:
if "main" in p.context.labels:
return p.context.resolve_label("main")
return None

@ -176,7 +176,7 @@ unlimited_regs: Allow an unlimited number of registers""",
cpu.setup_stack(cfg.stack_size) cpu.setup_stack(cfg.stack_size)
# launch the last loaded program # launch the last loaded program
cpu.launch(cpu.mmu.programs[-1], verbose=cfg.verbosity > 1) cpu.launch(verbose=cfg.verbosity > 1)
sys.exit(cpu.exit_code if not args.ignore_exit_code else 0) sys.exit(cpu.exit_code if not args.ignore_exit_code else 0)
except RiscemuBaseException as e: except RiscemuBaseException as e:

@ -31,6 +31,6 @@ if __name__ == "__main__":
cpu.setup_stack() cpu.setup_stack()
cpu.launch(program) cpu.launch()
sys.exit(cpu.exit_code) sys.exit(cpu.exit_code)

@ -1,13 +1,12 @@
import typing
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import List, Type, Callable, Set, Dict, TYPE_CHECKING from typing import List, Type, Callable, Set, Dict, TYPE_CHECKING, Iterable
from ..registers import Registers from ..registers import Registers
from ..config import RunConfig from ..config import RunConfig
from ..colors import FMT_RED, FMT_NONE, FMT_ERROR, FMT_CPU from ..colors import FMT_NONE, FMT_CPU
from . import T_AbsoluteAddress, Instruction, Program, ProgramLoader from . import T_AbsoluteAddress, Instruction, Program, ProgramLoader
if typing.TYPE_CHECKING: if TYPE_CHECKING:
from ..MMU import MMU from ..MMU import MMU
from ..instructions import InstructionSet from ..instructions import InstructionSet
@ -91,27 +90,26 @@ class CPU(ABC):
def run(self, verbose: bool = False): def run(self, verbose: bool = False):
pass pass
def launch(self, program: Program, verbose: bool = False): def launch(self, verbose: bool = False):
if program not in self.mmu.programs: entrypoint = self.mmu.find_entrypoint()
print(
FMT_ERROR + "[CPU] Cannot launch program that's not loaded!" + FMT_NONE if entrypoint is None:
) entrypoint = self.mmu.programs[0].entrypoint
return
if self.conf.verbosity > 0: if self.conf.verbosity > 0:
print( print(
FMT_CPU FMT_CPU
+ "[CPU] Started running from {}".format( + "[CPU] Started running from {}".format(
self.mmu.translate_address(program.entrypoint) self.mmu.translate_address(entrypoint)
) )
+ FMT_NONE + FMT_NONE
) )
print(program) self.pc = entrypoint
self.pc = program.entrypoint
self.run(verbose) self.run(verbose)
@classmethod @classmethod
@abstractmethod @abstractmethod
def get_loaders(cls) -> typing.Iterable[Type[ProgramLoader]]: def get_loaders(cls) -> Iterable[Type[ProgramLoader]]:
pass pass
def get_best_loader_for(self, file_name: str) -> Type[ProgramLoader]: def get_best_loader_for(self, file_name: str) -> Type[ProgramLoader]:

Loading…
Cancel
Save