Source code for bare68k.handler

from future.utils import raise_
import logging

from bare68k.consts import *
import bare68k.api.mem as mem
from bare68k.debug.cpusnapshot import *


[docs]class EventHandler(object): """define the event handling of the runtime""" def __init__(self, logger=None, snap_create=None, snap_formatter=None, instr_logger=None, mem_logger=None): # setup log channel if logger is None: self._log = logging.getLogger(__name__) else: self._log = logger # setup snapshot creator if snap_create is None: self._snap_create = CPUSnapshotCreator() else: self._snap_create = snap_create # setup snapshot formatter if snap_formatter is None: self._snap_formatter = CPUSnapshotFormatter() else: self._snap_formatter = snap_formatter # setup instr log channel if instr_logger is None: self._instr_log = logging.getLogger("bare68k.instr") else: self._instr_log = instr_logger # setup mem log channel if mem_logger is None: self._mem_log = logging.getLogger("bare68k.mem") else: self._mem_log = mem_logger # derive disassembler and formatter self._disasm = self._snap_create.get_disassembler() self._il_formatter = self._snap_formatter.get_instr_line_formatter() # the runtime backref will be set when attached to runtime self._runtime = None def attach_runtime(self, runtime): self._runtime = runtime # if label manager is used attach it to disassembler, too if runtime.get_with_labels(): label_mgr = runtime.get_label_mgr() self._disasm.set_label_mgr(label_mgr) def set_instr_logger(self, logger): self._instr_log = logger def set_mem_logger(self, logger): self._mem_log = logger def set_logger(self, logger): self._log = logger
[docs] def handle_cb_error(self, event): """a callback running your code raised an exception""" # get exception info exc_info = event.data # keyboard interrupt if exc_info[0] is KeyboardInterrupt: if self._runtime._run_cfg._catch_kb_intr: self._log.debug("keyboard interrupt (in callback)") return CPU_EVENT_USER_ABORT # re-raise other error self._log.error("handle CALLBACK raised: %s", exc_info[0].__name__) raise_(*exc_info)
[docs] def handle_reset(self, event): """default handler for reset opcode""" global _reset_end_pc pc = event.addr self._log.info("handle RESET @%08x", pc) # check if final PC reached to end run loop top_pc = self._runtime.get_top_end_pc() if top_pc is None or top_pc == pc: # quit run loop: return CPU_EVENT_DONE else: return CPU_EVENT_RESET
[docs] def handle_aline_trap(self, event): """an unbound aline trap was encountered""" # bound handler? bound_handler = event.data pc = event.addr op = event.value if bound_handler is not None: self._log.debug( "bound ALINE handler: @%08x: %04x -> %r", pc, op, bound_handler) bound_handler(event) else: self._log.warn("unbound ALINE encountered: @%08x: %04x", pc, op) return CPU_EVENT_ALINE_TRAP
[docs] def handle_mem_access(self, event): """default handler for invalid memory accesses""" mem_str = mem.get_cpu_mem_str(event.flags, event.addr, event.value) self._log.error("MEM ACCESS: %s", mem_str) # abort run loop if access was by caused by code if event.flags & MEM_FC_PROG_MASK == MEM_FC_PROG_MASK: return CPU_EVENT_MEM_ACCESS
[docs] def handle_mem_bounds(self, event): """default handler for invalid memory accesses beyond max pages""" mem_str = mem.get_cpu_mem_str(event.flags, event.addr, event.value) self._log.error("MEM BOUNDS: %s", mem_str) # abort run loop if access was by caused by code if event.flags & MEM_FC_PROG_MASK == MEM_FC_PROG_MASK: return CPU_EVENT_MEM_ACCESS
[docs] def handle_mem_trace(self, event): """a cpu mem trace handler returned a value != None""" mem_str = mem.get_cpu_mem_str(event.flags, event.addr, event.value) self._log.info("MEM_TRACE: %s -> %s", mem_str, event.data) return CPU_EVENT_MEM_TRACE
[docs] def handle_mem_special(self, event): """a memory special handler returned a value != None""" mem_str = mem.get_cpu_mem_str(event.flags, event.addr, event.value) self._log.info("MEM_SPECIAL: %s -> %s", mem_str, event.data) return CPU_EVENT_MEM_SPECIAL
[docs] def handle_instr_hook(self, event): """an instruction hook handler returned a value != None""" self._log.info("INSTR_HOOK: pc=@%08x -> %s", event.addr, event.data) return CPU_EVENT_INSTR_HOOK
[docs] def handle_int_ack(self, event): """int ack handler did return a value != None""" self._log.info("INT_ACK: pc=@%08x int=%d -> %s", event.addr, event.flags, event.data) return CPU_EVENT_INT_ACK
def handle_breakpoint(self, event): addr = event.addr bp_id = event.value mem_flags = event.flags mf_str = mem.get_cpu_fc_str(mem_flags) user_data = event.data self._log.info("BREAKPOINT: @%08x #%d flags=%s data=%s", addr, bp_id, mf_str, user_data) return CPU_EVENT_BREAKPOINT def handle_watchpoint(self, event): addr = event.addr bp_id = event.value mem_flags = event.flags mf_str = mem.get_cpu_access_str(mem_flags) user_data = event.data self._log.info("WATCHPOINT: @%08x #%d flags=%s data=%s", addr, bp_id, mf_str, user_data) return CPU_EVENT_WATCHPOINT def handle_timer(self, event): self._log.info("TIMER") # debug handler def handle_instr_trace(self, pc): # disassemble pc il, _ = self._disasm.disassemble(pc) # format line = self._il_formatter.format(il) # and log self._instr_log.info(line) def handle_cpu_mem_trace(self, msg, flag_addr_val): flags = flag_addr_val[0] # log only data access (not program) if flags & MEM_FC_DATA_MASK == MEM_FC_DATA_MASK: self._mem_log.info(msg) def handle_api_mem_trace(self, msg, flag_addr_val): self._mem_log.info(msg)