core: refactor how launch() works in preperation for libc integration
This commit is contained in:
parent
270c3e7090
commit
283bb1ae14
@ -72,7 +72,7 @@ class MMU:
|
||||
return sec
|
||||
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:
|
||||
if program.base <= addr < program.base + program.size:
|
||||
return program
|
||||
@ -192,7 +192,7 @@ class MMU:
|
||||
if not sec:
|
||||
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 []
|
||||
elf_markers = {
|
||||
"__global_pointer$",
|
||||
@ -347,3 +347,13 @@ class MMU:
|
||||
return sec.context
|
||||
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
||||
except RiscemuBaseException as e:
|
||||
|
@ -31,6 +31,6 @@ if __name__ == "__main__":
|
||||
|
||||
cpu.setup_stack()
|
||||
|
||||
cpu.launch(program)
|
||||
cpu.launch()
|
||||
|
||||
sys.exit(cpu.exit_code)
|
||||
|
@ -1,13 +1,12 @@
|
||||
import typing
|
||||
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 ..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
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
if TYPE_CHECKING:
|
||||
from ..MMU import MMU
|
||||
from ..instructions import InstructionSet
|
||||
|
||||
@ -91,27 +90,26 @@ class CPU(ABC):
|
||||
def run(self, verbose: bool = False):
|
||||
pass
|
||||
|
||||
def launch(self, program: Program, verbose: bool = False):
|
||||
if program not in self.mmu.programs:
|
||||
print(
|
||||
FMT_ERROR + "[CPU] Cannot launch program that's not loaded!" + FMT_NONE
|
||||
)
|
||||
return
|
||||
def launch(self, verbose: bool = False):
|
||||
entrypoint = self.mmu.find_entrypoint()
|
||||
|
||||
if entrypoint is None:
|
||||
entrypoint = self.mmu.programs[0].entrypoint
|
||||
|
||||
if self.conf.verbosity > 0:
|
||||
print(
|
||||
FMT_CPU
|
||||
+ "[CPU] Started running from {}".format(
|
||||
self.mmu.translate_address(program.entrypoint)
|
||||
self.mmu.translate_address(entrypoint)
|
||||
)
|
||||
+ FMT_NONE
|
||||
)
|
||||
print(program)
|
||||
self.pc = program.entrypoint
|
||||
self.pc = entrypoint
|
||||
self.run(verbose)
|
||||
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def get_loaders(cls) -> typing.Iterable[Type[ProgramLoader]]:
|
||||
def get_loaders(cls) -> Iterable[Type[ProgramLoader]]:
|
||||
pass
|
||||
|
||||
def get_best_loader_for(self, file_name: str) -> Type[ProgramLoader]:
|
||||
|
Loading…
Reference in New Issue
Block a user