Annotation of coherent/b/bin/db_400/trace2.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     trace2.c
                      3:  *
                      4:  *     The information contained herein is a trade secret of Mark Williams
                      5:  *     Company, and  is confidential information.  It is provided  under a
                      6:  *     license agreement,  and may be  copied or disclosed  only under the
                      7:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
                      8:  *     material without the express written authorization of Mark Williams
                      9:  *     Company or persuant to the license agreement is unlawful.
                     10:  *
                     11:  *     COHERENT Version 2.3.35
                     12:  *     Copyright (c) 1982, 1983, 1984.
                     13:  *     An unpublished work by Mark Williams Company, Chicago.
                     14:  *     All rights reserved.
                     15:  */
                     16: 
                     17: #include <stdio.h>
                     18: #include <ctype.h>
                     19: #include <errno.h>
                     20: #include <l.out.h>
                     21: #include <sys/ptrace.h>
                     22: #include <sys/timeout.h>
                     23: #include <sys/uproc.h>
                     24: #include <signal.h>
                     25: #include "trace.h"
                     26: #include "i8086.h"
                     27: 
                     28: /*
                     29:  * Talk to the user and try to solve his problems.
                     30:  */
                     31: process()
                     32: {
                     33:        register BPT *bp;
                     34:        /* register  */ int n;
                     35:        register int nibflag;
                     36:        register int bptflag;
                     37:        register caddr_t pc;
                     38:        register caddr_t fp;
                     39:        register int f;
                     40: 
                     41:        int             pcmd;
                     42:        char            ans[10];
                     43: 
                     44:        /*
                     45:         * Reverse-engineered pseudocode, minus global variable garbage.
                     46:         *
                     47:         * forever:
                     48:         *   execute(":x\n") <= Preload interpreter stack.
                     49:         *   (Will come back after traced process traps, e.g. after ":e".)
                     50:         *   forever:
                     51:         *     See if at call instruction.
                     52:         *     Install breakpoints, except at current instruction.
                     53:         *     See if current instruction is a breakpoint opcode.
                     54:         *     Start up traced process, full speed or single step.
                     55:         *     Report any error from ptrace call.
                     56:         *     Wait for traced process.
                     57:         *     Fetch registers and signal received from traced process.
                     58:         *     Replace breakpoints with instructions.
                     59:         *     If signal to child was not SIGTRAP
                     60:         *       display message
                     61:         *       execute(":f\n:x\n");
                     62:         *       continue inner loop
                     63:         *     Back up instruction pointer to start of the breakpoint.
                     64:         *     If single stepping
                     65:         *       Execute single step command string (sinp).
                     66:         *       If last single step in count
                     67:         *         execute(":x\n")
                     68:         *   end forever
                     69:         * end forever
                     70:         *
                     71:         */
                     72: top:
                     73:        bptflag = 0;
                     74:        execute(":x\n");
                     75:        for (;;) {
                     76:                /*
                     77:                 * Initialize flags.
                     78:                 */
                     79:                bitflag = 0;
                     80:                nibflag = 0;
                     81:                bp = 0;
                     82:        
                     83:                /*
                     84:                 * If in single step mode, set up for single step.
                     85:                 * If in SCONT mode, change to SCSET mode at call instruction.
                     86:                 */
                     87:                if (sinmode!=SNULL && sinmode!=SWAIT) {
                     88:                        bitflag = 1;
                     89:                        if (sinmode == SCONT)
                     90:                                setcont();
                     91:                }
                     92:        
                     93:                /*
                     94:                 * Place all breakpoints.
                     95:                 */
                     96:                if (reg.valid)
                     97:                        pc = getpc();
                     98: 
                     99:                for (n=NBPT, bp=&bpt[0]; n--; bp++) {
                    100:                        /* skip unused breakpoints */
                    101:                        if (bp->b_flag == 0)
                    102:                                continue;
                    103: 
                    104:                        /* fetch instruction at breakpoint address */
                    105:                        add = bp->b_badd;
                    106:                        if (getb(ISEG, bp->b_bins, sizeof(BIN)) == 0) {
                    107:                                printb(bp->b_badd);
                    108:                                goto err;
                    109:                        }
                    110: 
                    111:                        /* don't install breakpoint at current instruction */
                    112:                        if (reg.valid && bptflag && bp->b_badd==pc) {
                    113:                                bitflag = 1;
                    114:                                continue;
                    115:                        }
                    116: 
                    117:                        /* put in a breakpoint */
                    118:                        add = bp->b_badd;
                    119: fprintf(stderr, "replacing breakpoint at eip=%x\n", add);
                    120:                        if (putb(ISEG, bin, sizeof(BIN)) == 0) {
                    121:                                printb(bp->b_badd);
                    122:                                goto err;
                    123:                        }
                    124:                }
                    125:                bptflag = 0;
                    126: 
                    127:                /*
                    128:                 * Set flags and call machine dependent restore routine.
                    129:                 * Set "nibflag" if instruction at EIP is BRK.
                    130:                 */
                    131:                if (reg.valid && testbpt(pc))
                    132:                        nibflag = 1;
                    133: 
                    134:                /*
                    135:                 * restret() looks at bitflag and returns 1 if bitflag set.
                    136:                 * This is bogus.
                    137:                 * Mainly, restret() undoes the current breakpoint
                    138:                 * if it is done at a system call.
                    139:                 * This is probably unnecessary.
                    140:                 */
                    141: #if 0
                    142:                if (restret() == 0)
                    143:                        goto err;
                    144: #endif
                    145:        
                    146:                /*
                    147:                 * Start up the child.
                    148:                 */
                    149:                errno = 0;
                    150:                switch (sinmode) {
                    151:                case SNULL:
                    152:                case SWAIT:
                    153:                        pcmd = PTRACE_RESUME;
                    154:                        break;
                    155:                case SCSET:
                    156:                case SCONT:
                    157:                case SSTEP:
                    158:                        pcmd = PTRACE_SSTEP;
                    159:                        break;
                    160:                }
                    161:                ptrace(pcmd, pid, 1, 0);
                    162:                if (errno) {
                    163:                        perror("ptrace");
                    164:                        goto err;
                    165:                }
                    166:                if (waitc() == 0)
                    167:                        goto err;
                    168:        
                    169: #if 0
                    170: /* whatever this is, it looks unnecessary. */
                    171:                if (trapint() == 0)
                    172:                        goto err;
                    173: #endif
                    174: 
                    175:                /*
                    176:                 * Copy registers into ureg, and thence to r.
                    177:                 * Why are there two register sets?  I don't know - hws
                    178:                 */
                    179:                if (setregs() == 0)
                    180:                        goto err;
                    181: 
                    182:                /*
                    183:                 * Set f to the signal number sent to the traced process
                    184:                 * and global "trapstr" to its name.
                    185:                 */
                    186:                if ((f=settrap()) == 0)
                    187:                        goto err;
                    188:        
                    189:                /*
                    190:                 * Replace breakpoints with instructions.
                    191:                 */
                    192: fprintf(stderr, "Replace breakpoints with instructions\n");
                    193:                for (n=NBPT, bp=bpt; n--; bp++) {
                    194:                        if (bp->b_flag == 0)
                    195:                                continue;
                    196:                        add = bp->b_badd;
                    197:                        if (putb(ISEG, bp->b_bins, sizeof(BIN)) == 0) {
                    198:                                printb(bp->b_badd);
                    199:                                goto err;
                    200:                        }
                    201:                }
                    202:        
                    203:                /*
                    204:                 * If latest signal to traced process was not SIGTRAP,
                    205:                 * tell the user, then accept input.
                    206:                 */
                    207:                if (f != SIGTRAP) {
                    208:                        fprintf(stderr,
                    209:                          "Traced process did not stop at a breakpoint\n");
                    210:                        execute(":f\n:x\n");
                    211:                        continue;
                    212:                }
                    213: 
                    214:                /*
                    215:                 * Find the breakpoint we are at.
                    216:                 * Back up pc to start of the breakpoint.
                    217:                 */
                    218:                bp = 0;
                    219:                pc = getpc() - sizeof(BIN);
                    220:                if (bitflag==0 || nibflag) {
                    221:                        for (n=NBPT, bp=&bpt[0]; n--; bp++) {
                    222:                                if (bp->b_flag == 0)
                    223:                                        continue;
                    224:                                if (bp->b_badd != pc)
                    225:                                        continue;
                    226: fprintf(stderr, "found bp at %x\n", pc);
                    227:                                setpc((caddr_t)pc);
                    228:                                bptflag = 1;
                    229:                                break;
                    230:                        }
                    231:                        if (bp==&bpt[NBPT]) {
                    232:                                bp = 0;
                    233:                        }
                    234:                }
                    235: 
                    236:                /*
                    237:                 * If in single step mode, execute command.
                    238:                 */
                    239:                switch (sinmode) {
                    240:                case SCSET:
                    241: fprintf(stderr, "sinmode=SCSET\n");
                    242:                        break;
                    243:                case SNULL:
                    244: fprintf(stderr, "sinmode=SNULL\n");
                    245:                        break;
                    246:                case SWAIT:
                    247: fprintf(stderr, "sinmode=SWAIT\n");
                    248:                        break;
                    249:                case SCONT:
                    250: fprintf(stderr, "sinmode=SCONT\n");
                    251:                        break;
                    252:                case SSTEP:
                    253: fprintf(stderr, "sinmode=SSTEP\n");
                    254:                        break;
                    255:                }
                    256:                switch (sinmode) {
                    257:                case SSTEP:
                    258:                case SCONT:
                    259:                        execute(sinp);
                    260:                        if (--sindecr == 0)
                    261:                                execute(":x\n");
                    262:                        continue;
                    263:                case SCSET:
                    264:                        for (n=0; n<NBPT; n++)
                    265:                                bpt[n].b_flag &= ~BSIN;
                    266:                        sinmode = SWAIT;
                    267:                        /* put a BSIN breakpoint at the return address */
                    268:                        intcont();
                    269:                        break;
                    270:                }
                    271: 
                    272:                /*
                    273:                 * If we got an unexpected trace trap or unknown
                    274:                 * breakpoint, we handle it here.
                    275:                 */
                    276:                if (bp == NULL) {
                    277:                        if (bitflag==0 || nibflag) {
                    278:                                fprintf(stderr,
                    279:                                  "Unexpected trace trap or breakpoint\n");
                    280:                                execute(":f\n:x\n");
                    281:                        }
                    282:                        continue;
                    283:                }
                    284: 
                    285:                /*
                    286:                 * Single step breakpoints have highest priority.
                    287:                 */
                    288:                fp = getfp();
                    289:                if (bp->b_flag & BSIN) {
                    290:                        if (bp->b_sfpt==0 || bp->b_sfpt==fp) {
                    291:                                bp->b_flag &= ~BSIN;
                    292:                                if (sinmode == SWAIT) {
                    293: fprintf(stderr, "SCWAIT->SCONT??\n");
                    294:                                        sinmode = SCONT;
                    295:                                        execute(sinp);
                    296:                                        if (--sindecr == 0)
                    297:                                               execute(":x\n");
                    298:                                        continue;
                    299:                                }
                    300:                        }
                    301:                }
                    302: 
                    303:                /*
                    304:                 * Return breakpoints are next.
                    305:                 */
                    306:                if (bp->b_flag & BRET) {
                    307:                        if (fp == bp->b_rfpt) {
                    308:                                bp->b_flag &= ~BRET;
                    309:                                execute(bp->b_rcom);
                    310:                                continue;
                    311:                        }
                    312:                }
                    313: 
                    314:                /*
                    315:                 * Your conventional everyday ordinary breakpoint.
                    316:                 */
                    317:                if (bp->b_flag & BBPT) {
                    318:                        execute(bp->b_bcom);
                    319:                        continue;
                    320:                }
                    321:        }
                    322: 
                    323:        /*
                    324:         * Something is terribly wrong.  Kill off our child,
                    325:         * and generally reset everything to the start.
                    326:         */
                    327: err:
                    328:        killc();
                    329:        reslout();
                    330:        bptinit();
                    331:        goto top;
                    332: }
                    333: 
                    334: /*
                    335:  * Given a command line in `miscbuf', parse the command line, kill the
                    336:  * current child and start up a new one.  0 is returned on success, 1
                    337:  * on failure.
                    338:  */
                    339: runfile()
                    340: {
                    341:        register char *bp, *cp;
                    342:        register int c;
                    343:        char *ifn, *ofn, *argl[ARGSIZE];
                    344:        int qflag, aflag, n;
                    345: 
                    346:        killc();
                    347:        if (objflag == 0) {
                    348:                printe("No executable");
                    349:                return 1;
                    350:        }
                    351:        ifn = NULL;
                    352:        ofn = NULL;
                    353:        qflag = 0;
                    354:        aflag = 0;
                    355:        n = 0;
                    356:        bp = miscbuf;
                    357:        cp = miscbuf;
                    358:        c = *bp++;
                    359:        while (c != '\n') {
                    360:                switch (c) {
                    361:                case '<':
                    362:                        ifn = cp;
                    363:                        c = *bp++;
                    364:                        break;
                    365:                case '>':
                    366:                        ofn = cp;
                    367:                        if ((c=*bp++) == '>') {
                    368:                                aflag = 1;
                    369:                                c = *bp++;
                    370:                        }
                    371:                        break;
                    372:                default:
                    373:                        if (n >= ARGSIZE-1) {
                    374:                                printe("Too many arguments");
                    375:                                return 1;
                    376:                        }
                    377:                        argl[n++] = cp;
                    378:                }
                    379:                while (qflag || !isascii(c) || !isspace(c)) {
                    380:                        if (c == '\n')
                    381:                                break;
                    382:                        if (c == '"') {
                    383:                                qflag ^= 1;
                    384:                                c = *bp++;
                    385:                                continue;
                    386:                        }
                    387:                        if (c == '\\') {
                    388:                                if ((c=*bp++) == '\n') {
                    389:                                        printe("Syntax error");
                    390:                                        return 1;
                    391:                                }
                    392:                        }
                    393:                        *cp++ = c;
                    394:                        c = *bp++;
                    395:                }
                    396:                if (qflag) {
                    397:                        printe("Missing \"");
                    398:                        return 1;
                    399:                }
                    400:                *cp++ = '\0';
                    401:                if (c == '\n')
                    402:                        break;
                    403:                while (isascii(c) && isspace(c))
                    404:                        c = *bp++;
                    405:        }
                    406:        if (n == 0)
                    407:                argl[n++] = lfn;
                    408:        argl[n] = NULL;
                    409:        if (startup(argl, ifn, ofn, aflag) == 0)
                    410:                return 1;
                    411:        return 0;
                    412: }
                    413: 
                    414: /*
                    415:  * Start execution of the child.  `argv' is the argument list, `ifnp' is
                    416:  * the name of the input file, `ofnp' is the name of the output file and
                    417:  * `appf' tells us whether the output file is opened for append or write.
                    418:  */
                    419: startup(argv, ifnp, ofnp, appf)
                    420: char **argv;
                    421: char *ifnp;
                    422: char *ofnp;
                    423: {
                    424:        register int n;
                    425: 
                    426:        if ((pid=fork()) < 0) {
                    427:                printr("Cannot fork");
                    428:                return 0;
                    429:        }
                    430:        if (pid == 0) {
                    431:                if (ifnp != NULL) {
                    432:                        if ((n=open(ifnp, 0)) < 0)
                    433:                                panic("Cannot open %s", ifnp);
                    434:                        dup2(n, 0);
                    435:                        close(n);
                    436:                }
                    437:                if (ofnp != NULL) {
                    438:                        n = -1;
                    439:                        if (appf) {
                    440:                                if ((n=open(ofnp, 1)) >= 0)
                    441:                                        lseek(n, 0L, 2);
                    442:                        }
                    443:                        if (n < 0) {
                    444:                                if ((n=creat(ofnp, 0644)) < 0)
                    445:                                        panic("%s: cannot create", ofnp);
                    446:                        }
                    447:                        dup2(n, 1);
                    448:                        close(n);
                    449:                }
                    450:                ptrace(PTRACE_SETUP, 0, NULL, 0);
                    451:                execv(lfn, argv);
                    452:                exit (1);
                    453:        }
                    454:        if (waitc() == 0)
                    455:                return 0;
                    456:        clramap();
                    457:        DSPACE = setsmap(NULL, (off_t)0, (off_t)LI, (off_t)0,
                    458:                        getp, putp, DSEG);
                    459:        ISPACE = setsmap(NULL, (off_t)0, (off_t)LI, (off_t)0,
                    460:                        getp, putp, ISEG);
                    461:        USPACE = setsmap(NULL, (off_t)0, (off_t)UPASIZE, (off_t)0,
                    462:                        getp, putp, USEG);
                    463:        excflag = 1;
                    464:        regflag = 1;
                    465:        return 1;
                    466: }
                    467: 
                    468: /*
                    469:  * Given a newly started child, find out necessary information.
                    470:  */
                    471: shiftup()
                    472: {
                    473:        if (trapint() == 0)
                    474:                return 0;
                    475:        if (setregs() == 0)
                    476:                return 0;
                    477:        return settrap();
                    478: }
                    479: 
                    480: /*
                    481:  * Kill off our child.
                    482:  */
                    483: killc()
                    484: {
                    485:        if (excflag) {
                    486:                ptrace(PTRACE_TERM, pid, 0, 0);
                    487:                waitc();
                    488:        }
                    489:        excflag = 0;
                    490:        regflag = 0;
                    491:        trapstr = NULL;
                    492:        reg.valid = 0;
                    493: }
                    494: 
                    495: /*
                    496:  * Wait for the traced process to stop.
                    497:  */
                    498: waitc()
                    499: {
                    500:        register int p;
                    501:        int s;
                    502:        extern errno;
                    503: 
                    504:        while ((p=wait(&s)) != pid) {
                    505:                if (p >= 0) {
                    506:                        printr("Adopted a child %d", p);
                    507:                        continue;
                    508:                }
                    509:                if (intflag == 0) {
                    510:                        excflag = 0;
                    511:                        printr("Nonexistent child");
                    512:                        return 0;
                    513:                }
                    514:                intflag = 0;
                    515:        }
                    516:        if ((s&0xff) != 0x7f) {
                    517:                excflag = 0;
                    518:                printr("Child process terminated (%x)", (s>>8)&0xff );
                    519:                return 0;
                    520:        }
                    521:        return 1;
                    522: }
                    523: 
                    524: 
                    525: /******************************************************************************
                    526:  *
                    527:  * Note some #defines in these include files interferes with
                    528:  * items in preceeding include files. Hence the strange
                    529:  * program order.
                    530:  *
                    531:  ******************************************************************************/
                    532: 
                    533: #include <coff.h>
                    534: 
                    535: /*
                    536:  * Reset segmentation for an coff or l.out format.
                    537:  */
                    538: reslout()
                    539: {
                    540:        FILEHDR         coffh;
                    541:        struct ldheader ldh;
                    542: 
                    543:        clramap();
                    544:        objflag = 0;
                    545: 
                    546:        fseek(lfp, (long)0, 0);
                    547:        if (fread(&coffh, sizeof(coffh), 1, lfp) != 1) {
                    548:                printr("Can't read object file");
                    549:                return 0;
                    550:        }
                    551: 
                    552:        if (coffh.f_magic == C_386_MAGIC) {
                    553: #if 0
                    554:                /* get entry point from optional coff header */
                    555:                struct aouthdr  opth;
                    556: 
                    557:                reg.r_ip = 0xA8;
                    558:                if (coffh.f_opthdr >= sizeof(struct aouthdr)) {
                    559:                        if (fread(&opth, sizeof(struct aouthdr), 1, lfp) == 1) 
                    560:                                reg.r_ip = opth.entry;
                    561:                }
                    562: #endif
                    563:                objflag = 1;
                    564:                setcoffseg(lfp, &coffh);
                    565:                return 1;
                    566:        } else {
                    567:                fseek(lfp, (long)0, 0);
                    568:                if (fread(&ldh, sizeof(ldh), 1, lfp) != 1) {
                    569:                        printr("Can't read object file");
                    570:                        return 0;
                    571:                }
                    572:                canlout(&ldh);
                    573:                if (ldh.l_magic != L_MAGIC) {
                    574:                        printr("not an object file");
                    575:                        return 0;
                    576:                }
                    577:                objflag = 1;
                    578:                setaseg(&ldh);
                    579:                return 1;
                    580:        }
                    581: }
                    582: 
                    583: /* end of trace2.c */

unix.superglobalmegacorp.com

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