|
|
1.1 ! root 1: #include "process.pub" ! 2: #include "frame.pri" ! 3: #include "symtab.pri" ! 4: #include "symbol.h" ! 5: #include "hostcore.h" ! 6: #include <a.out.h> ! 7: #include "asm.pri" ! 8: #include "format.pub" ! 9: #include "bpts.pri" ! 10: #include "master.pri" ! 11: #include <machine/vmparam.h> ! 12: SRCFILE("hostcore.c") ! 13: #define TXTOFF(magic) (magic==ZMAGIC ? 0 : sizeof (struct exec)) ! 14: ! 15: Behavs HostCore::behavetype() { return behavs(); } ! 16: char *HostCore::eventname() { return SignalName(event()); } ! 17: char *HostCore::run() { return ioctl(PIOCRUN); } ! 18: char *HostCore::stop() { return sendsig(SIGSTOP); } ! 19: int HostCore::event() { return pr.p_cursig; } ! 20: long HostCore::scratchaddr() { return 0x2000; } ! 21: ! 22: long HostCore::regaddr() ! 23: { ! 24: return (long)u()->u_ar0; ! 25: } ! 26: ! 27: #define SUNBPT 0x4e4f /* Trap #15 */ ! 28: char *HostCore::laybpt(Trap *t) ! 29: { ! 30: t->saved = peek(t->stmt->range.lo)->sht; ! 31: return poke(t->stmt->range.lo, SUNBPT, 2); ! 32: } ! 33: ! 34: Behavs HostCore::behavs() ! 35: { ! 36: if( !online() ) ! 37: return PENDING; ! 38: char *error = readcontrol(); ! 39: if( error ){ ! 40: behavs_problem = sf( "readcontrol(): %s", error ); ! 41: return ERRORED; ! 42: } ! 43: switch( pr.p_stat ){ ! 44: case SSLEEP: ! 45: case SRUN: ! 46: return ACTIVE; ! 47: case SSTOP: ! 48: switch( pr.p_cursig ){ ! 49: case SIGSTOP: ! 50: return HALTED; ! 51: case SIGTRAP: ! 52: return BREAKED; ! 53: default: ! 54: return PENDING; ! 55: } ! 56: } ! 57: behavs_problem = sf( "pr.p_stat=%d", pr.p_stat); ! 58: return ERRORED; ! 59: } ! 60: ! 61: char *HostCore::problem() ! 62: { ! 63: if( corefstat() ) ! 64: return "core image has gone away"; ! 65: return Core::problem(); ! 66: } ! 67: ! 68: char *HostCore::readcontrol() ! 69: { ! 70: char *error; ! 71: ! 72: if( corefstat() ) ! 73: return "cannot fstat core image"; ! 74: if( online() ){ ! 75: if( ::ioctl( corefd, PIOCGETPR, &pr ) < 0 ) ! 76: return SysErr("fetching proc struct:"); ! 77: if( error = read( USRADR, uarea(), ctob(UPAGES)) ) ! 78: return error; ! 79: } else { ! 80: if( error = read( USRADR, uarea(), ctob(UPAGES)) ) ! 81: return error; ! 82: pr = *(struct proc *)(uarea() + *(int *)u()->u_stack - UADDR); ! 83: } ! 84: return 0; ! 85: } ! 86: ! 87: char *HostCore::open() ! 88: { ! 89: int mode = 2; ! 90: while( procpath() && corefd<0 && mode>=0 ) ! 91: corefd = ::open(procpath(), mode--); ! 92: if( procpath() && corefd<0 ) return SysErr("core image: " ); ! 93: if( procpath() && corefstat() ) ! 94: return SysErr("core image: " ); ! 95: if( corestat.st_mode & S_IEXEC ) ! 96: return "executable - should be process (/proc/123) or dump (core)"; ! 97: if( stabpath() ){ ! 98: stabfd = ::open(stabpath(),0); ! 99: if( stabfd<0 ) return SysErr( "symbol tables: " ); ! 100: } ! 101: proc dummy_pr; ! 102: if( ::ioctl(corefd, PIOCGETPR, &dummy_pr) == 0 ){ ! 103: _online = 1; ! 104: if( stabpath() == 0 ) ! 105: stabfd = ::ioctl(corefd, PIOCOPENT, 0); ! 106: } ! 107: stabfstat(); ! 108: _symtab = new Ed8SymTab(this, stabfd, _symtab); ! 109: _symtab->read(); ! 110: return procpath() ? readcontrol() : 0; ! 111: } ! 112: ! 113: char *HostCore::reopen(char *newprocpath, char *newstabpath) ! 114: { ! 115: int mode = 2, newcorefd = -1, compstabfd = -1; ! 116: ! 117: while( newprocpath && newcorefd<0 && mode>=0 ) ! 118: newcorefd = ::open(newprocpath, mode--); ! 119: if( newcorefd<0 ) ! 120: return "cannot open process"; ! 121: proc dummy_pr; ! 122: if( ::ioctl(newcorefd, PIOCGETPR, &dummy_pr) ) ! 123: return "not a live process"; ! 124: if( newstabpath ) ! 125: compstabfd = ::open(newstabpath, 0); ! 126: else ! 127: compstabfd = ::ioctl(newcorefd, PIOCOPENT, 0); ! 128: struct stat compstabstat; ! 129: if( compstabfd < 0 || ::fstat(compstabfd, &compstabstat) ){ ! 130: ::close(newcorefd); ! 131: return "symbol table error"; ! 132: } ! 133: if( compstabstat.st_mtime != stabstat.st_mtime ) ! 134: return "symbol tables differ (modified time)"; ! 135: if( compstabstat.st_size != stabstat.st_size ) ! 136: return "symbol tables differ (file size)"; ! 137: ::close(corefd); ! 138: corefd = newcorefd; ! 139: ::close(compstabfd); ! 140: return readcontrol(); ! 141: } ! 142: ! 143: #define ATTEMPTS 9 /* core file i/o */ ! 144: #define SLEEP 2 ! 145: ! 146: char *HostCore::seekto(int &fd, long &addr, int &whence) ! 147: { ! 148: long maxadr; ! 149: ! 150: if( !online() ) { ! 151: if( addr < 0x2000 ) ! 152: return "offset below text segment"; ! 153: else if( addr < (maxadr = ctob(u()->u_tsize + 1))) { ! 154: addr += TXTOFF(_symtab->magic()) - 0x2000; ! 155: fd = stabfd; ! 156: } ! 157: else if( addr < (maxadr = ctob(stoc(ctos(u()->u_tsize+1)))) ) ! 158: return "offset below data segment"; ! 159: else if( addr < (maxadr += ctob(u()->u_dsize)) ) { ! 160: addr = addr - (maxadr - ctob(u()->u_dsize)) ! 161: + ctob(UPAGES); ! 162: } ! 163: else if( addr < (SYSADR - ctob(u()->u_ssize)) ) ! 164: return "offset beyond data segment"; ! 165: else if( addr < SYSADR ) ! 166: { addr -= SYSADR; whence = 2; } ! 167: else if( addr >= USRADR ) ! 168: addr -= USRADR; ! 169: else ! 170: return "offset in system space"; ! 171: } ! 172: return 0; ! 173: } ! 174: ! 175: char *memcpy(char*,char*,int); ! 176: ! 177: char *HostCore::readwrite(long offset, char *buf, int r, int w) ! 178: { ! 179: int fd = corefd, whence = 0, attempts = ATTEMPTS; ! 180: extern int errno; ! 181: char *msg = "core image:"; ! 182: ! 183: if( corefstat() ) ! 184: return "core image fstat error"; ! 185: char *error = seekto(fd, offset, whence); ! 186: if( error ) ! 187: return sf("core image: %s", error); ! 188: while(--attempts>=0){ ! 189: if( lseek(fd, offset, whence) == -1 ) ! 190: return sf("lseek(%d,0x%X,%d)", fd, offset, whence); ! 191: if( r ){ ! 192: int got = ::read(fd, buf, r); ! 193: for( int i = got; i < r; ++i ) buf[i] = 0; ! 194: if( got > 0 ) return 0; ! 195: } ! 196: if( w && ::write(fd, buf, w) == w ) return 0; ! 197: if( errno != EBUSY ) break; ! 198: if( online() ){ ! 199: const SPRBUSY = (SLOCK|SSWAP|SPAGE|SKEEP|SDLYU|SWEXIT ! 200: |SVFORK|SVFDONE|SNOVM|SPROCIO); ! 201: msg = sf("core p_flag=0x%x: ", pr.p_flag); ! 202: if( !(pr.p_flag&SPRBUSY) ) break; ! 203: if( pr.p_flag&SPAGE ) ++attempts; ! 204: } ! 205: sleep(SLEEP); ! 206: } ! 207: return SysErr(msg); ! 208: } ! 209: ! 210: int HostCore::instack(long curfp, long prevfp ) ! 211: { ! 212: return curfp < SYSADR && curfp > prevfp; ! 213: } ! 214: ! 215: int HostCore::fpvalid(long fp) ! 216: { ! 217: return instack(fp, 0x08000000); ! 218: } ! 219: ! 220: char *HostCore::ioctl(int p) ! 221: { ! 222: if( !online() ) ! 223: return "process: not live"; ! 224: if( ::ioctl( corefd, p, 0 )< 0 ) ! 225: return SysErr( "process control: " ); ! 226: return 0; ! 227: } ! 228: ! 229: char *HostCore::signalmask(long mask) ! 230: { ! 231: if( ::ioctl(corefd,PIOCSMASK,&mask)<0 ) ! 232: return SysErr( "setting trace mask:" ); ! 233: return 0; ! 234: } ! 235: ! 236: #define PSW_T 0x00008000 ! 237: char *HostCore::pswT() ! 238: { ! 239: long ps = ((long *)(uarea() + (long)u()->u_ar0 - UADDR))[PS]; ! 240: ps |= PSW_T; ! 241: return regpoke(REG_PS(), ps); ! 242: } ! 243: ! 244: static Alarm; ! 245: static void SigCatch(int) ! 246: { ! 247: extern int errno; ! 248: trace("SigCatch()"); ! 249: Alarm = 1; ! 250: errno = 0; ! 251: } ! 252: ! 253: const int STEPWAIT = 15; ! 254: ! 255: char *HostCore::waitstop() ! 256: { ! 257: int oldalarm; ! 258: char *error = 0; ! 259: ! 260: oldalarm = alarm(STEPWAIT); ! 261: SIG_TYP oldsig = signal(SIGALRM, (SIG_ARG_TYP)&SigCatch); ! 262: Alarm = 0; ! 263: error = ioctl(PIOCWSTOP); ! 264: signal(SIGALRM, (SIG_ARG_TYP)oldsig); ! 265: alarm(oldalarm); ! 266: if( Alarm ){ ! 267: ioctl(PIOCSTOP); ! 268: sleep(2); ! 269: return sf("timeout (%d secs)", STEPWAIT); ! 270: } ! 271: return error; ! 272: } ! 273: ! 274: const short M68K_TRAP0=0x4E40, M68K_RTS = 0x4E75; ! 275: ! 276: char *HostCore::dostep(long lo, long hi, int sstep) ! 277: { ! 278: char *error = 0; ! 279: long fp0, time0, time(long); ! 280: ! 281: time0 = ::time(0L); ! 282: fp0 = fp(); ! 283: for(;;){ ! 284: if( hi && isM68KJSB(peek(pc())->sht) ) { ! 285: error = stepoverM68KJSB(); ! 286: goto next; ! 287: } ! 288: if (sstep) ! 289: error = pswT(); ! 290: if( !error && (event()==SIGTRAP || event()==SIGSTOP) ) ! 291: error = clrcurrsig(); ! 292: if( !error ) error = run(); ! 293: if( !error ) error = waitstop(); ! 294: if( !error ) error = readcontrol(); ! 295: if( !error && event()!=SIGTRAP ) ! 296: error = sf( "single step error. signal=%d", event() ); ! 297: if( !error ) error = clrcurrsig(); ! 298: next: ! 299: if( error ) return error; ! 300: if( !hi || pc()<lo || pc()>=hi || ! 301: (fp()>fp0 && peek(pc())->sht != M68K_RTS) ) ! 302: return 0; ! 303: if( ::time(0L) > time0+STEPWAIT ) ! 304: return sf("single step timeout (%d secs)",STEPWAIT); ! 305: } ! 306: } ! 307: ! 308: char *HostCore::resources() ! 309: { ! 310: static char buf[64]; ! 311: ! 312: sprintf( buf, "%.1fu %.1fs", ! 313: (double)u()->u_vm.vm_utime/50, (double)u()->u_vm.vm_stime/50 ); ! 314: return buf; ! 315: } ! 316: ! 317: void Wait3() ! 318: { ! 319: #define WNOHANG 1 /* see <wait.h> */ ! 320: int wait3(int*,int,int*); ! 321: for( int i = 0; i<10 && wait3(0,WNOHANG,0)>0; ++i ) {} /* 10? */ ! 322: } ! 323: ! 324: char *HostCore::destroy() ! 325: { ! 326: clrcurrsig(); ! 327: char *error = sendsig(SIGKILL); ! 328: Wait3(); ! 329: return error; ! 330: } ! 331: ! 332: char *HostCore::clrcurrsig() ! 333: { ! 334: char *error = ioctl(PIOCCSIG); ! 335: if( !error ) ! 336: pr.p_cursig = 0; ! 337: return error; ! 338: } ! 339: ! 340: char *HostCore::sendsig(long sig) ! 341: { ! 342: if( !online() ) return "send signal: process not live"; ! 343: if( ::ioctl(corefd, PIOCKILL, &sig) >= 0 ) ! 344: return 0; ! 345: return SysErr( "send signal (PIOCKILL): " ); ! 346: } ! 347: ! 348: Context* HostCore::newContext() ! 349: { ! 350: HostContext *cc = new HostContext; ! 351: cc->error = 0; ! 352: cc->core = this; ! 353: cc->pending = 0; ! 354: if( pr.p_stat != SSTOP ) ! 355: cc->error = "context save: process not stopped"; ! 356: else if( peek(pc()-2)->sht == M68K_TRAP0 ) ! 357: cc->error = "context save: process in system call"; ! 358: else if( cc->pending = pr.p_cursig ) ! 359: cc->error = clrcurrsig(); ! 360: if( !cc->error ) ! 361: for( int i = 0; i < 18; ++i ) ! 362: cc->regs[i] = regpeek(i); ! 363: return cc; ! 364: } ! 365: ! 366: void HostContext::restore() // should use only PIOCSSIG eventually ! 367: { ! 368: if( pending ){ ! 369: if( ::ioctl(core->corefd, PIOCSSIG, &pending) == 0 ) ! 370: core->pr.p_cursig = pending; ! 371: else { ! 372: static once = 0; ! 373: if( once++ == 0 ) ! 374: PadsWarn("warning: unix out of date?: PIOCSSIG"); ! 375: if( error = core->sendsig(pending) ) ! 376: return; ! 377: if( pending == SIGTRAP ){ ! 378: if( error = core->run() ) return; ! 379: if( error = core->waitstop() ) return; ! 380: error = core->readcontrol(); ! 381: } else ! 382: error = core->step(); // other signals ! 383: if( error ) ! 384: return; ! 385: } ! 386: } ! 387: for( int i = 0; i < 18; ++i ) ! 388: if( error = core->regpoke(i, regs[i]) ) ! 389: return; ! 390: } ! 391: ! 392: void WaitForExecHang(char *procpath) ! 393: { ! 394: int fd = open(procpath, 0); ! 395: for( int i = 1; i <= 15; ++i ){ ! 396: proc p; ! 397: if( ::ioctl(fd, PIOCGETPR, &p) >= 0 ){ ! 398: if( p.p_stat == SSTOP ){ ! 399: close(fd); ! 400: return; ! 401: } ! 402: } ! 403: sleep(1); ! 404: } ! 405: close(fd); ! 406: } ! 407:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.