Annotation of researchv9/jtools/src/pi/v9core.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.