Annotation of researchv9/jtools/src/pi/hostcore.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: SRCFILE("hostcore.c")
                     12: #define        TXTOFF(magic)   (magic==ZMAGIC ? 0 : sizeof (struct exec))
                     13: #include <setjmp.h>
                     14: 
                     15: static WaitList waitlist;
                     16: int kill(int,int);
                     17: 
                     18: const int STOPPED=0, RUNNING=1, EXITED=2, DIED=3;
                     19: const REGADDR = USRADR - 18 * 4;
                     20: 
                     21: Behavs HostCore::behavetype()          { return behavs(); }
                     22: char *HostCore::eventname()            { return SignalName(event()); }
                     23: char *HostCore::stop()                 { ::kill(pid, SIGSTOP); return 0; }
                     24: int HostCore::event()                  { return cursig; }
                     25: long HostCore::regaddr()               { return REGADDR; }
                     26: long HostCore::scratchaddr()           { return 0x2000; }
                     27: 
                     28: extern int errno;
                     29: 
                     30: int HostCore::ptrace(int cmd, int a, int d, int a2)
                     31: {
                     32:        errno = 0;
                     33:        int ret = ::ptrace(cmd, pid, a, d, a2);
                     34:        switch (cmd) {
                     35:                case PTRACE_CONT:
                     36:                case PTRACE_KILL:
                     37:                case PTRACE_SINGLESTEP:
                     38:                case PTRACE_ATTACH:
                     39:                case PTRACE_DETACH:
                     40:                        break;
                     41:                default:
                     42:                        if (!errno)
                     43:                                waitlist.wait(this, WAIT_DISCARD);
                     44:                        break;
                     45:        }
                     46:        return ret;
                     47: }
                     48: 
                     49: char *HostCore::run()
                     50: {
                     51:        if (cursig == SIGSTOP || cursig == SIGTRAP)
                     52:                cursig = 0;
                     53:        ptrace(PTRACE_CONT, 1, cursig);
                     54:        state = RUNNING;
                     55:        cursig = 0;
                     56:        return 0;
                     57: }
                     58: 
                     59: #define SUNBPT 0x4e4f                  /* Trap #15 */
                     60: char *HostCore::laybpt(Trap *t)
                     61: {
                     62:        Cslfd *cp = peek(t->stmt->range.lo, 0);
                     63:        if (!cp)
                     64:                return "text not readable (probably shared)";
                     65:        t->saved = cp->sht;
                     66:        return poke(t->stmt->range.lo, SUNBPT, 2);
                     67: }
                     68: 
                     69: Behavs HostCore::behavs()
                     70: {
                     71:        if( !online() )
                     72:                return PENDING;
                     73:        // Confirm it is still running
                     74:        if ( state == EXITED || state == DIED)
                     75:                return ERRORED;
                     76:        if ( state == RUNNING ) {
                     77:                if (waitlist.wait(this, WAIT_POLL|WAIT_PCFIX)) {
                     78:                        if (state != STOPPED)
                     79:                                return ERRORED;
                     80:                        if (!(sigmask&(1<<(cursig-1)))) {
                     81:                                run();
                     82:                                return ACTIVE;
                     83:                        }
                     84:                } else
                     85:                        return ACTIVE;
                     86:        } 
                     87:        switch( cursig ){
                     88:        case SIGSTOP:
                     89:                return HALTED;
                     90:        case SIGTRAP:
                     91:                return BREAKED;
                     92:        default:
                     93:                return PENDING;
                     94:        }
                     95: }
                     96: 
                     97: char *HostCore::problem()
                     98: {
                     99:        static char buf[64];
                    100: 
                    101:        if( !online() ) {
                    102:                if( corefstat() )
                    103:                        return "core image has gone away";
                    104:                return Core::problem();
                    105:        }
                    106:        if (state == EXITED)
                    107:                sprintf( buf, "exited with status %d", cursig);
                    108:        else if (state == DIED)
                    109:                sprintf( buf, "died from signal %d", cursig);
                    110:        return buf;
                    111: }
                    112: 
                    113: char *HostCore::readcontrol()
                    114: {
                    115:        if( online() )
                    116:                return "online readcontrol";
                    117:        if( corefstat() )
                    118:                return "cannot fstat core image";
                    119:        int got = ::read(corefd, (char *)&bsdcore, sizeof(bsdcore));
                    120:        if (got != sizeof(bsdcore))
                    121:                return "cannot read bsdcore";
                    122:        state = STOPPED;
                    123:        cursig = bsdcore.c_signo;
                    124:        endtext = N_TXTADDR(bsdcore.c_aouthdr) + bsdcore.c_tsize;
                    125:        startdata = N_DATADDR(bsdcore.c_aouthdr);
                    126:        enddata = startdata + bsdcore.c_dsize;
                    127:        startstack = SYSADR - bsdcore.c_ssize;
                    128:        return 0;
                    129: }
                    130: 
                    131: void HostCore::close()
                    132: {
                    133:        if (online()){
                    134:                if (state == RUNNING) {
                    135:                        stop();
                    136:                        waitstop(WAIT_PCFIX);
                    137:                        ptrace(PTRACE_DETACH, 1);
                    138:                } else if (state == STOPPED) {
                    139:                        ::kill(pid, SIGSTOP);
                    140:                        ptrace(PTRACE_DETACH, 1);
                    141:                }
                    142:                waitlist.remove(this);
                    143:        }
                    144:        Core::close();
                    145: }
                    146: 
                    147: char *HostCore::open()
                    148: {
                    149:        int mode = 2;
                    150:        if( procpath() && !strcmp(basename(procpath()), "core") ) {
                    151:                while( corefd<0 && mode>=0 )
                    152:                        corefd = ::open(procpath(), mode--);
                    153:                if( corefd<0 )
                    154:                        return SysErr("core image: " );
                    155:                if( corefstat() )
                    156:                        return SysErr("core image: " );
                    157:                if( corestat.st_mode & S_IEXEC )
                    158:                        return "executable - should be dump (core)";
                    159:        } else if( procpath() ) {
                    160:                sscanf(procpath(), "%d", &pid);
                    161:                _online = 1;
                    162:                waitlist.add(this);
                    163:                waitlist.wait(this, 0);
                    164:                cursig = SIGSTOP;
                    165:        }
                    166:        stabfd = ::open(stabpath(),0);
                    167:        if( stabfd<0 ) {
                    168:                if( online() ) {
                    169:                        ::kill(pid, SIGSTOP);
                    170:                        ptrace(PTRACE_DETACH, 1);
                    171:                }
                    172:                return SysErr( "symbol tables: " );
                    173:        }
                    174:        stabfstat();
                    175:        BsdSymTab *bsdsp = new BsdSymTab(this, stabfd, _symtab);
                    176:        _symtab = bsdsp;
                    177:        _symtab->read();
                    178:        // Can't find endtext from U structure in 4.0 release, this is a kludge
                    179:        endtext = bsdsp->endtext();
                    180:        if( online() || !procpath() )
                    181:                return 0;
                    182:        return readcontrol();
                    183: }
                    184: 
                    185: char *HostCore::reopen(char *newprocpath, char *newstabpath)
                    186: {
                    187:        int compstabfd = -1;
                    188:        char *error = 0;
                    189:        int retstat;
                    190: 
                    191:        if( !online() || (newprocpath && !strcmp(basename(newprocpath), "core")) )
                    192:                return "reopen core not implemented";
                    193:        int opid = pid;
                    194:        int ostate = state;
                    195:        int ocursig = cursig;
                    196:        sscanf(newprocpath, "%d", &pid);
                    197:        waitlist.wait(this, 0);
                    198:        
                    199:        compstabfd = ::open(newstabpath, 0);
                    200:        struct stat compstabstat;
                    201:        if( compstabfd < 0 ) {
                    202:                error = "symbol table error";
                    203:                goto out;
                    204:        }
                    205:        retstat = ::fstat(compstabfd, &compstabstat);
                    206:        ::close(compstabfd);
                    207:        if (retstat)
                    208:                error = "symbol table error";
                    209:        else if( compstabstat.st_mtime != stabstat.st_mtime )
                    210:                error = "symbol tables differ (modified time)";
                    211:        else if( compstabstat.st_size != stabstat.st_size )
                    212:                error = "symbol tables differ (file size)";
                    213:        cursig = ocursig;
                    214:        state = ostate;
                    215:        if (error) {
                    216: out:
                    217:                ::kill(pid, SIGSTOP);
                    218:                ptrace(PTRACE_DETACH, 1);
                    219:                pid = opid;
                    220:                return error;
                    221:        }
                    222:        // Must disconnect  from the old process
                    223:        int npid = pid;
                    224:        pid = opid;
                    225:        switch (state) {
                    226:                case RUNNING:
                    227:                        stop();
                    228:                        waitstop(WAIT_PCFIX);
                    229:                        ptrace(PTRACE_DETACH, 1);
                    230:                        break;
                    231:                case STOPPED:
                    232:                        ::kill(pid, SIGSTOP);
                    233:                        ptrace(PTRACE_DETACH, 1);
                    234:                        break;
                    235:                case EXITED:
                    236:                case DIED:
                    237:                        break;
                    238:        }
                    239:        pid = npid;
                    240:        state = STOPPED;
                    241:        cursig = SIGSTOP;
                    242:        // Can't find endtext from U structure in 4.0 release, this is a kludge
                    243:        BsdSymTab *bsdsp = (BsdSymTab *)_symtab;
                    244:        endtext = bsdsp->endtext();
                    245:        return 0;
                    246: }
                    247: 
                    248: const int REGFD = -2, DATAFD = -3, TEXTFD = -4, USERFD = -5;
                    249: char *HostCore::seekto(int &fd, long &addr, int &whence)
                    250: {
                    251:        if( !online() ) {
                    252:                if ( (u_long)addr >= USRADR) {
                    253:                        addr -= USRADR + ctob(UPAGES);
                    254:                        whence = 2;
                    255:                } else if ( (u_long)addr >= REGADDR) {
                    256:                        addr -= REGADDR;
                    257:                        fd = REGFD;
                    258:                } else if ( (u_long)addr < 0x2000)
                    259:                        return "offset below text segment";
                    260:                else if ( (u_long)addr <= endtext) {
                    261:                        addr += N_TXTOFF(bsdcore.c_aouthdr)
                    262:                                - N_TXTADDR(bsdcore.c_aouthdr);
                    263:                        fd = stabfd;
                    264:                } else if ( (u_long)addr < startdata)
                    265:                        return "offset beyond text segment";
                    266:                else if ( (u_long)addr <= enddata)
                    267:                        addr -= startdata - bsdcore.c_len;
                    268:                else if ( (u_long)addr < startstack)
                    269:                        return "offset beyond data segment";
                    270:                else if ( (u_long)addr < SYSADR) {
                    271:                        addr -= SYSADR + ctob(UPAGES);
                    272:                        whence = 2;
                    273:                } else
                    274:                        return "offset in system space";
                    275:        } else {
                    276:                if ( (u_long)addr >= USRADR) {
                    277:                        addr -= USRADR;
                    278:                        fd = USERFD;
                    279:                } else if ( (u_long)addr >= REGADDR) {
                    280:                        addr -= REGADDR;
                    281:                        fd = REGFD;
                    282:                } else if ( (u_long)addr >= SYSADR ) {
                    283:                        extern char *DEVKMEM;
                    284:                        if( kmemfd == -1 ) {
                    285:                                kmemfd = ::open(DEVKMEM, 0);
                    286:                                if (kmemfd == -1)
                    287:                                        return "can't read kernel";
                    288:                        }
                    289:                        fd = kmemfd;
                    290:                } else if ( (u_long)addr <= endtext)
                    291:                        fd = TEXTFD;
                    292:                else
                    293:                        fd = DATAFD;
                    294:        }
                    295:        return 0;
                    296: }
                    297: 
                    298: void bcopy(char*,char*,int);
                    299: 
                    300: char *HostCore::readwrite(long offset, char *buf, int r, int w)
                    301: {
                    302:        int fd = corefd, whence = 0;
                    303:        int rv;
                    304:        char *msg = "core image:";
                    305: 
                    306:        char *error = seekto(fd, offset, whence);
                    307:        if( error )
                    308:                return sf("core image: %s", error);
                    309:        if( fd >= 0 ) {
                    310:                if( lseek(fd, offset, whence) == -1 )
                    311:                        return sf("lseek(%d,0x%X,%d)", fd, offset, whence);
                    312:                if( r ){
                    313:                        int got = ::read(fd, buf, r);
                    314:                        for( int i = got; i < r; ++i ) buf[i] = 0;
                    315:                        if( got > 0 ) return 0;
                    316:                }
                    317:                if( w && ::write(fd, buf, w) == w ) return 0;
                    318:                return SysErr(msg);
                    319:        }
                    320:        int wasrunning = 0;
                    321:        if (state == RUNNING) {
                    322:                stop();
                    323:                if (error = waitstop(WAIT_PCFIX))
                    324:                        return error;
                    325:                if (cursig != SIGSTOP) {
                    326:                        int savesig = cursig;
                    327:                        /* The STOP signal still has to be eaten */
                    328:                        run();
                    329:                        waitstop(WAIT_PCFIX);
                    330:                        cursig = savesig;
                    331:                } else
                    332:                        wasrunning = 1;
                    333:        }
                    334:        if (fd == REGFD) {
                    335:                error = regrw(offset, buf, r, w);
                    336:                if (wasrunning && !error)
                    337:                        run();
                    338:                return error;
                    339:        } else if (fd == DATAFD) {
                    340:                if ( r )
                    341:                        rv = ptrace(PTRACE_READDATA, offset, r, (int)buf);
                    342:                else
                    343:                        rv = ptrace(PTRACE_WRITEDATA, offset, w, (int)buf);
                    344:        }
                    345:        else if (fd == TEXTFD) {
                    346:                if ( r )
                    347:                        rv = ptrace(PTRACE_READTEXT, offset, r, (int)buf);
                    348:                else {
                    349:                        /* Damn bug in Sun's kernel */
                    350:                        if (w < 4){
                    351:                                int tmp;
                    352:                                ptrace(PTRACE_READTEXT, offset, 4, (int)&tmp);
                    353:                                ::bcopy(buf, (char*)&tmp, w);
                    354:                                if (rv = ptrace(PTRACE_WRITETEXT, offset, 4, (int)&tmp))
                    355:                                        return "text not writable (probably shared)";
                    356:                        } else
                    357:                                rv = ptrace(PTRACE_WRITETEXT, offset, w, (int)buf);
                    358:                }
                    359:        }
                    360:        else if (fd == USERFD) {
                    361:                int *ip = (int *)buf;
                    362:                if ( r ) {
                    363:                        do {
                    364:                                *ip++ = ptrace(PTRACE_PEEKUSER, offset);
                    365:                                offset += 4;
                    366:                                r -= 4;
                    367:                        } while (r > 0 && errno == 0);
                    368:                } else {
                    369:                        do {
                    370:                                ptrace(PTRACE_POKEUSER, offset, *ip++);
                    371:                                offset += 4;
                    372:                                w -= 4;
                    373:                        } while (w > 0 && errno == 0);
                    374:                }
                    375:                rv = errno;
                    376:        }
                    377:        if (wasrunning && !rv)
                    378:                run();
                    379:        return rv == 0 ? 0 : "bad ptrace call";
                    380: }
                    381: 
                    382: char *HostCore::regrw(long offset, char *buf, int r, int w)
                    383: {
                    384:        if ( online() ) {
                    385:                regs rg;
                    386:                if ( ptrace(PTRACE_GETREGS, (int)&rg) )
                    387:                        return "Can't read registers";
                    388:                if ( r )
                    389:                        ::bcopy( (char*)&rg + offset, buf, r);
                    390:                else {
                    391:                        ::bcopy( buf, (char*)&rg + offset, w);
                    392:                        ptrace(PTRACE_SETREGS, (int)&rg);
                    393:                }
                    394:        } else {
                    395:                if ( r )
                    396:                        ::bcopy( (char*)&bsdcore.c_regs + offset, buf, r);
                    397:                else if ( w )
                    398:                        ::bcopy( buf, (char*)&bsdcore.c_regs + offset, w);
                    399:        }
                    400:        return 0;
                    401: }
                    402: 
                    403: int HostCore::instack(long curfp, long prevfp )
                    404: {
                    405:        return ((curfp&0xf8000000)==0x08000000) && ((curfp&0xff000000)!=0x0f000000)
                    406:                 && (curfp>prevfp);
                    407: }
                    408: 
                    409: int HostCore::fpvalid(long fp)
                    410: {
                    411:        return (instack(fp, 0x08000000) && fp < 0x0f000000);
                    412: }
                    413: 
                    414: char *HostCore::signalmask(long mask)
                    415: {
                    416:        sigmask = mask;
                    417:        return 0;
                    418: }
                    419: 
                    420: char   *HostCore::exechang(long ehang)
                    421: {
                    422:        if (!ehang)
                    423:                return "Must hang on exec"; 
                    424:        return 0;
                    425: }
                    426: 
                    427: #define PSW_T   0x00008000
                    428: char *HostCore::pswT(long psw_loc, int t)
                    429: {
                    430:        long ps;
                    431: 
                    432:        char *error = read(psw_loc, (char*) &ps, 4 );
                    433:        if( error ) return error;
                    434:        if( t )
                    435:                ps |= PSW_T;
                    436:        else
                    437:                ps &= ~PSW_T;
                    438:        return write(psw_loc, (char*)&ps, 4);
                    439: }
                    440: 
                    441: static jmp_buf saveenv;
                    442: void longjmp(jmp_buf, int);
                    443: int setjmp(jmp_buf);
                    444: 
                    445: static void SigCatch(int)
                    446: {
                    447:        longjmp(saveenv, 1);
                    448: }
                    449: 
                    450: const int STEPWAIT = 15;
                    451: 
                    452: char *HostCore::waitstop(int flags)
                    453: {
                    454:        int wret;
                    455: 
                    456:        SIG_TYP oldsig = ::signal(SIGALRM, (SIG_TYP)&SigCatch);
                    457:        int oldalarm = ::alarm(STEPWAIT);
                    458:        if( ::setjmp(saveenv) ){
                    459:                ::alarm(oldalarm);
                    460:                ::signal(SIGALRM, (SIG_TYP)oldsig);
                    461:                ::kill(pid, SIGSTOP);
                    462:                return sf("timeout (%d secs)", STEPWAIT);
                    463:        }
                    464:        wret = waitlist.wait(this, flags);
                    465:        ::alarm(oldalarm);
                    466:        ::signal(SIGALRM, (SIG_TYP)oldsig);
                    467:        if (!wret )
                    468:                return "Unexpected wait error";
                    469:        if (state != STOPPED)
                    470:                return "Process exited";
                    471:        return 0;
                    472: }
                    473: 
                    474: const short M68K_TRAP0=0x4E40, M68K_RTS = 0x4E75;
                    475: 
                    476: char *HostCore::dostep(long lo, long hi, int sstep)
                    477: {
                    478:        char *error = 0;
                    479:        long fp0, time0, time(long);
                    480: 
                    481:        time0 = ::time(0L);
                    482:        fp0 = fp();
                    483:        for(;;){
                    484:                if( hi && isM68KJSB(peek(pc())->sht) ) {
                    485:                        error = stepoverM68KJSB();
                    486:                        goto next;
                    487:                }
                    488:                if (sstep)
                    489:                        ptrace(PTRACE_SINGLESTEP, 1);
                    490:                else
                    491:                        error = run();
                    492:                if( !error ) error = waitstop(sstep ? 0 : WAIT_PCFIX);
                    493:                if( !error && event()!=SIGTRAP )
                    494:                        error = sf( "single step error. signal=%d", event() );
                    495:                if( !error ) error = clrcurrsig();
                    496: next:
                    497:                if( error ) return error;
                    498:                if( !hi || pc()<lo || pc()>=hi ||
                    499:                    (fp()>fp0 && peek(pc())->sht != M68K_RTS) )
                    500:                        return 0;
                    501:                if( ::time(0L) > time0+STEPWAIT )
                    502:                        return sf("single step timeout (%d secs)",STEPWAIT);
                    503:        }
                    504: }
                    505: 
                    506: char *HostCore::destroy()
                    507: {
                    508:        char *error;
                    509: 
                    510:        if ( state == EXITED || state == DIED)
                    511:                return 0;
                    512:        clrcurrsig();
                    513:        if (state == RUNNING) {
                    514:                stop();
                    515:                if (error = waitstop(WAIT_PCFIX))
                    516:                        return error;
                    517:        }
                    518:        ptrace(PTRACE_KILL);
                    519:        waitlist.wait(this, WAIT_DISCARD|WAIT_POLL);
                    520:        state = EXITED;
                    521:        cursig = SIGKILL;
                    522:        return 0;
                    523: }
                    524: 
                    525: char *HostCore::clrcurrsig()
                    526: {
                    527:        cursig = 0;
                    528:        return 0;
                    529: }
                    530: 
                    531: char *HostCore::sendsig(long sig)
                    532: {
                    533:        if( !online() ) return "send signal: process not live";
                    534:        ::kill(pid, sig);
                    535:        return 0;
                    536: }
                    537: 
                    538: Context* HostCore::newContext()
                    539: {
                    540:        HostContext *cc = new HostContext;
                    541:        cc->error = 0;
                    542:        cc->core = this;
                    543:        cc->pending = 0;
                    544:        if( state != STOPPED )
                    545:                cc->error = "context save: process not stopped";
                    546:        else if( peek(pc()-2)->sht == M68K_TRAP0 )
                    547:                cc->error = "context save: process in system call";
                    548:        else if( cc->pending = cursig )
                    549:                cc->error = clrcurrsig();
                    550:        if( !cc->error )
                    551:                for( int i = 0; i < 18; ++i )
                    552:                        cc->regs[i] = regpeek(i);
                    553:        return cc;
                    554: }
                    555: 
                    556: void HostContext::restore()
                    557: {
                    558:        if( pending )
                    559:                core->cursig = pending;
                    560:        for( int i = 0; i < 18; ++i )
                    561:                if( error = core->regpoke(i, regs[i]) )
                    562:                        return;
                    563: }

unix.superglobalmegacorp.com

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