#include "process.pub" #include "frame.pri" #include "symtab.pri" #include "symbol.h" #include "rtcore.h" #include "asm.pri" #include "format.pub" #include "bpts.pri" #include "master.pri" SRCFILE("rtcore.c") Behavs RtCore::behavs() { readcontrol(); return behavetype(); } char *RtCore::destroy() { rtabort(); return 0; } int RtCore::event() { return state; } int RtCore::fpvalid(long fp) { return fp != 0; } int RtCore::instack(long curfp, long prevfp) { return (curfp>prevfp); } char *RtCore::readcontrol() { state = rtstate(); return 0; } long RtCore::regaddr() { return rtregaddr(); } char *RtCore::run() { rtgo(); return 0; } long RtCore::scratchaddr() { int dummy; return rtscratchaddr(&dummy); } char *RtCore::stop() { rtstop(); return 0; } char *RtCore::eventname() { switch (state) { case P_DEAD: return "no process"; case P_RUNNING: return "running"; case P_TRACED: return "traced"; case P_BKPT: return "breakpoint"; case P_BUSERR: return "bus error"; case P_ADDRERR: return "address error"; default: return "unknown state"; } } #define SUNBPT 0x4e4f /* Trap #15 */ char *RtCore::laybpt(Trap *t) { t->saved = peek(t->stmt->range.lo)->sht; return poke(t->stmt->range.lo, SUNBPT, 2); } Behavs RtCore::behavetype() { switch( state ){ case P_RUNNING: return ACTIVE; case P_TRACED: case P_BKPT: return BREAKED; case P_STOPPED: return HALTED; case P_DEAD: case P_BUSERR: case P_ADDRERR: default: return PENDING; } } char *RtCore::open() { if( stabpath() ){ stabfd = ::open(stabpath(),0); if( stabfd<0 ) return SysErr( "symbol tables: " ); } _online = 1; stabfstat(); _symtab = new BsdSymTab(this, stabfd, _symtab); _symtab->read(); return readcontrol(); } char *RtCore::reopen(char *, char *newstabpath) { int compstabfd = -1; compstabfd = ::open(newstabpath, 0); struct stat compstabstat; if( compstabfd < 0 || ::fstat(compstabfd, &compstabstat) ) return "symbol table error"; if( compstabstat.st_mtime != stabstat.st_mtime ) return "symbol tables differ (modified time)"; if( compstabstat.st_size != stabstat.st_size ) return "symbol tables differ (file size)"; ::close(compstabfd); return readcontrol(); } char *RtCore::readwrite(long offset, char *buf, int r, int w) { if( r ){ if (rtread(offset, buf, r) != r) return "core read error"; return 0; } if( w && rtwrite(offset, buf, w) == w ) return 0; return 0; } #define PSW_T 0x00008000 char *RtCore::pswT() { long ps = regpeek(REG_PS()); ps |= PSW_T; return regpoke(REG_PS(), ps); } static Alarm; static void SigCatch(int) { extern int errno; ::Alarm = 1; errno = 0; } const short M68K_RTS = 0x4E75; const int STEPWAIT = 15; char *RtCore::waitstop() { int oldalarm; char *error = 0; SIG_TYP oldsig = signal(SIGALRM, (SIG_TYP)&SigCatch); oldalarm = alarm(STEPWAIT); ::Alarm = 0; rtwait(); signal(SIGALRM, (SIG_TYP)oldsig); alarm(oldalarm); if( ::Alarm ){ rtstop(); return sf("timeout (%d secs)", STEPWAIT); } return error; } char *RtCore::dostep(long lo, long hi, int sstep) { char *error = 0; long fp0, time0, time(long); time0 = ::time(0L); fp0 = fp(); for(;;){ if( hi && isM68KJSB(peek(pc())->sht) ) { error = stepoverM68KJSB(); goto next; } if (sstep) error = pswT(); if( !error ) error = run(); if( !error ) error = waitstop(); if( !error ) error = readcontrol(); if( !error && event()!=P_TRACED && event()!=P_BKPT) error = sf( "single step error. signal=%d", event() ); next: if( error ) return error; if( !hi || (fp()>fp0 && peek(pc())->sht != M68K_RTS) || pc()=hi) return 0; if( ::time(0L) > time0+STEPWAIT ) return sf("single step timeout (%d secs)",STEPWAIT); } }