Annotation of coherent/b/bin/db_400/trace2.c, revision 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.