Annotation of 43BSDReno/bin/adb/common_source/pcs.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)pcs.c      5.5 (Berkeley) 4/9/89";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * adb - subprocess control
        !             7:  */
        !             8: 
        !             9: #include "defs.h"
        !            10: #include "bkpt.h"
        !            11: #include <machine/reg.h>       /* for getpc() *//* XXX */
        !            12: #include <sys/file.h>
        !            13: #include <sys/ptrace.h>
        !            14: #include <sys/wait.h>
        !            15: 
        !            16: extern char NOBKPT[];
        !            17: extern char SZBKPT[];
        !            18: extern char EXBKPT[];
        !            19: extern char NOPCS[];
        !            20: extern char BADMOD[];
        !            21: extern char NOFORK[];
        !            22: extern char ENDPCS[];
        !            23: extern char BADWAIT[];
        !            24: 
        !            25: struct bkpt *bkpthead;         /* head of breakpoint list */
        !            26: 
        !            27: static long runcount;          /* number of times to loop past breakpoints */
        !            28: 
        !            29: /* bpstate remembers whether we have installed the breakpoints */
        !            30: static enum { BPOUT, BPIN } bpstate;
        !            31: 
        !            32: char   *malloc();
        !            33: 
        !            34: /* run modes */
        !            35: #define        CONTINUOUS      0
        !            36: #define        SINGLESTEP      1
        !            37: 
        !            38: /* sub process control */
        !            39: 
        !            40: subpcs(modif)
        !            41:        int modif;
        !            42: {
        !            43:        register int check;
        !            44:        register struct bkpt *bp;
        !            45:        int execsig, runmode;
        !            46:        char *comptr;
        !            47: 
        !            48:        switch (modif) {
        !            49: 
        !            50:        case 'd':
        !            51:                /* delete breakpoint */
        !            52:                if ((bp = scanbkpt(dot)) == NULL)
        !            53:                        error(NOBKPT);
        !            54:                bp->state = BKPT_FREE;
        !            55:                return;
        !            56: 
        !            57:        case 'D':
        !            58:                /* delete all breapoints */
        !            59:                for (bp = bkpthead; bp != NULL; bp = bp->next)
        !            60:                        bp->state = BKPT_FREE;
        !            61:                return;
        !            62: 
        !            63:        case 'b':
        !            64:        case 'B':
        !            65:                /* set breakpoint */
        !            66:                if ((bp = scanbkpt(dot)) == NULL) {
        !            67:                        /* find a free one, or make one */
        !            68:                        for (bp = bkpthead; bp != NULL; bp = bp->next)
        !            69:                                if (bp->state == BKPT_FREE)
        !            70:                                        break;
        !            71:                        if (bp == NULL) {
        !            72:                                bp = (struct bkpt *)malloc(sizeof *bp);
        !            73:                                if (bp == NULL)
        !            74:                                        error(EXBKPT);
        !            75:                                bp->next = bkpthead;
        !            76:                                bkpthead = bp;
        !            77:                        }
        !            78:                }
        !            79:                bp->loc = dot;
        !            80:                bp->initcnt = bp->count = ecount;
        !            81:                bp->state = BKPT_SET;
        !            82:                check = MAX_BKPTCOM - 1;
        !            83:                comptr = bp->comm;
        !            84:                (void) rdc();
        !            85:                unreadc();
        !            86:                do {
        !            87:                        *comptr++ = readchar();
        !            88:                } while (check-- && lastc != '\n');
        !            89:                *comptr = 0;
        !            90:                unreadc();
        !            91:                if (check == 0)
        !            92:                        error(SZBKPT);
        !            93:                return;
        !            94: 
        !            95:        case 'k':
        !            96:        case 'K':
        !            97:                /* kill process */
        !            98:                if (pid == 0)
        !            99:                        error(NOPCS);
        !           100:                adbprintf("%d: killed", pid);
        !           101:                endpcs();
        !           102:                return;
        !           103: 
        !           104:        case 'r':
        !           105:        case 'R':
        !           106:                /* run program */
        !           107:                endpcs();
        !           108:                setup();
        !           109:                runcount = ecount;
        !           110:                runmode = CONTINUOUS;
        !           111:                execsig = 0;
        !           112:                /* if starting at a breakpoint, run over it */
        !           113:                if (scanbkpt(gavedot ? dot : entrypc()) != NULL)
        !           114:                        runcount++;
        !           115:                break;
        !           116: 
        !           117:        case 's':
        !           118:        case 'S':
        !           119:                /* single step, with optional signal */
        !           120:                runcount = ecount;
        !           121:                if (pid) {
        !           122:                        runmode = SINGLESTEP;
        !           123:                        execsig = oexpr() ? expv : signo;
        !           124:                } else {
        !           125:                        setup();
        !           126:                        runmode = SINGLESTEP;
        !           127:                        execsig = 0;
        !           128:                        runcount--;
        !           129:                }
        !           130:                break;
        !           131: 
        !           132:        case 'c':
        !           133:        case 'C':
        !           134:        case 0:
        !           135:                /* continue with optional signal */
        !           136:                runcount = ecount;
        !           137:                if (pid == 0)
        !           138:                        error(NOPCS);
        !           139:                runmode = CONTINUOUS;
        !           140:                execsig = oexpr() ? expv : signo;
        !           141:                break;
        !           142: 
        !           143:        default:
        !           144:                error(BADMOD);
        !           145:                /* NOTREACHED */
        !           146:        }
        !           147: 
        !           148:        if (runcount > 0 && runpcs(runmode, execsig))
        !           149:                adbprintf("breakpoint%16t");
        !           150:        else
        !           151:                adbprintf("stopped at%16t");
        !           152:        delbp();
        !           153:        printpc();
        !           154: }
        !           155: 
        !           156: /*
        !           157:  * Print all breakpoints.
        !           158:  */
        !           159: printbkpts()
        !           160: {
        !           161:        register struct bkpt *b;
        !           162: 
        !           163:        adbprintf("breakpoints\ncount%8tbkpt%24tcommand\n");
        !           164:        for (b = bkpthead; b != NULL; b = b->next) {
        !           165:                if (b->state != BKPT_FREE) {
        !           166:                        adbprintf("%-8.8D", b->count);
        !           167:                        psymoff("%R", b->loc, SP_INSTR, maxoff, "%24t");
        !           168:                        prints(b->comm);
        !           169:                }
        !           170:        }
        !           171: }
        !           172: 
        !           173: /*
        !           174:  * Remove (restore to original instruction(s)) all breakpoints.
        !           175:  */
        !           176: delbp()
        !           177: {
        !           178:        register struct bkpt *b;
        !           179: 
        !           180:        if (bpstate != BPOUT) {
        !           181:                for (b = bkpthead; b != NULL; b = b->next)
        !           182:                        if (b->state != BKPT_FREE && clr_bpt(b))
        !           183:                                bperr(b, "clear");
        !           184:                bpstate = BPOUT;
        !           185:        }
        !           186: }
        !           187: 
        !           188: /*
        !           189:  * Insert all breakpoints.
        !           190:  */
        !           191: setbp()
        !           192: {
        !           193:        register struct bkpt *b;
        !           194: 
        !           195:        if (bpstate != BPIN) {
        !           196:                for (b = bkpthead; b != NULL; b = b->next)
        !           197:                        if (b->state != BKPT_FREE && set_bpt(b))
        !           198:                                bperr(b, "set");
        !           199:                bpstate = BPIN;
        !           200:        }
        !           201: }
        !           202: 
        !           203: static
        !           204: bperr(b, how)
        !           205:        struct bkpt *b;
        !           206:        char *how;
        !           207: {
        !           208: 
        !           209:        adbprintf("cannot %s breakpoint: ", how);
        !           210:        psymoff("%R", b->loc, SP_INSTR, maxoff, "\n");
        !           211: }
        !           212: 
        !           213: /*
        !           214:  * Run subprocess for a while.
        !           215:  * Return true iff stopped due to breakpoint.
        !           216:  */
        !           217: int
        !           218: runpcs(runmode, execsig)
        !           219:        int runmode, execsig;
        !           220: {
        !           221:        register struct bkpt *bkpt;
        !           222:        int rc;
        !           223: 
        !           224:        /* always set pc, so that expr>pc works too */
        !           225:        setpc(gavedot ? dot : getpc());
        !           226:        adbprintf("%s: running\n", symfile.name);
        !           227:        while (--runcount >= 0) {
        !           228:                /* BEGIN XXX (machine dependent?, delete ptrace, etc) */
        !           229:                if (runmode == SINGLESTEP)
        !           230:                        delbp();        /* hardware handles single-stepping */
        !           231:                else {  /* continuing from a breakpoint is hard */
        !           232:                        if ((bkpt = scanbkpt(getpc())) != NULL) {
        !           233:                                execbkpt(bkpt, execsig);
        !           234:                                execsig = 0;
        !           235:                        }
        !           236:                        setbp();
        !           237:                }
        !           238:                (void) ptrace(runmode == CONTINUOUS ? PT_CONTINUE : PT_STEP,
        !           239:                        pid, (int *)getpc(), execsig);
        !           240:                /* END XXX */
        !           241: 
        !           242:                /* paranoia, SP_DATA usually sufficient, but this is easy */
        !           243:                cacheinval(SP_INSTR | SP_DATA);
        !           244: 
        !           245:                bpwait();
        !           246:                checkerr();
        !           247:                execsig = 0;
        !           248:                delbp();
        !           249:                readregs();
        !           250: 
        !           251:                if (signo != 0 || (bkpt = scanbkpt(getpc())) == NULL) {
        !           252:                        execsig = signo;
        !           253:                        rc = 0;
        !           254:                        continue;
        !           255:                }
        !           256:                /* stopped by BPT instruction */
        !           257: #ifdef DEBUG
        !           258:                adbprintf("\n BPT code: comm=%s%8tstate=%d",
        !           259:                    bkpt->comm, bkpt->state);
        !           260: #endif
        !           261:                dot = bkpt->loc;
        !           262:                switch (bkpt->state) {
        !           263:                        char *p;
        !           264: 
        !           265:                case BKPT_SET:
        !           266:                        bkpt->state = BKPT_TRIPPED;
        !           267:                        if (*bkpt->comm == '\n')
        !           268:                                break;
        !           269:                        p = lp;
        !           270:                        command(bkpt->comm, ':');
        !           271:                        lp = p;
        !           272:                        if (gavedot && edot == 0) /* maybe dot==0 ??? */
        !           273:                                break;
        !           274:                        if (--bkpt->count == 0)
        !           275:                                break;
        !           276:                        /* FALLTHROUGH */
        !           277: 
        !           278:                case BKPT_TRIPPED:
        !           279:                        execbkpt(bkpt, execsig);
        !           280:                        execsig = 0;
        !           281:                        runcount++;
        !           282:                        continue;
        !           283: 
        !           284:                default:
        !           285:                        panic("runpcs");
        !           286:                        /* NOTREACHED */
        !           287:                }
        !           288:                bkpt->count = bkpt->initcnt;
        !           289:                rc = 1;
        !           290:        }
        !           291:        return (rc);
        !           292: }
        !           293: 
        !           294: endpcs()
        !           295: {
        !           296:        register struct bkpt *bp;
        !           297: 
        !           298:        if (pid) {
        !           299:                (void) ptrace(PT_KILL, pid, (int *)0, 0);       /* XXX */
        !           300:                pid = 0;
        !           301:                for (bp = bkpthead; bp != NULL; bp = bp->next)
        !           302:                        if (bp->state != BKPT_FREE)
        !           303:                                bp->state = BKPT_SET;
        !           304:        }
        !           305:        bpstate = BPOUT;
        !           306: }
        !           307: 
        !           308: #ifdef VFORK
        !           309: nullsig()
        !           310: {
        !           311: 
        !           312: }
        !           313: #endif
        !           314: 
        !           315: setup()
        !           316: {
        !           317: 
        !           318:        cacheinval(SP_INSTR | SP_DATA); /* paranoia */
        !           319:        (void) close(symfile.fd);
        !           320:        symfile.fd = -1;
        !           321: #ifndef VFORK
        !           322: #define vfork fork
        !           323: #endif
        !           324:        if ((pid = vfork()) == 0) {
        !           325:                (void) ptrace(PT_TRACE_ME, 0, (int *)0, 0);     /* XXX */
        !           326: #ifdef VFORK
        !           327:                (void) signal(SIGTRAP, nullsig);
        !           328: #endif
        !           329:                (void) signal(SIGINT, sigint);
        !           330:                (void) signal(SIGQUIT, sigquit);
        !           331:                doexec();
        !           332:                exit(0);
        !           333:        } else if (pid == -1) {
        !           334:                pid = 0;
        !           335:                error(NOFORK);
        !           336:        } else {
        !           337:                bpwait();
        !           338:                readregs();
        !           339:                symfile.fd = open(symfile.name, wtflag);
        !           340:                if (errflag) {
        !           341:                        adbprintf("%s: cannot execute\n", symfile.name);
        !           342:                        endpcs();
        !           343:                        error((char *)0);
        !           344:                }
        !           345:        }
        !           346:        bpstate = BPOUT;
        !           347: }
        !           348: 
        !           349: /*
        !           350:  * Single step over a location containing a breakpoint.
        !           351:  */
        !           352: execbkpt(bp, execsig)
        !           353:        struct bkpt *bp;
        !           354:        int execsig;
        !           355: {
        !           356: 
        !           357: #ifdef DEBUG
        !           358:        adbprintf("exbkpt: %d\n", bp->count);
        !           359: #endif
        !           360:        delbp();
        !           361:        (void) ptrace(PT_STEP, pid, (int *)bp->loc, execsig);   /* XXX */
        !           362:        bp->state = BKPT_SET;
        !           363:        bpwait();
        !           364:        checkerr();
        !           365:        readregs();
        !           366: }
        !           367: 
        !           368: static char separators[] = "<> \t\n";
        !           369: 
        !           370: doexec()
        !           371: {
        !           372:        register char *p, **ap;
        !           373:        register int c;
        !           374:        char *argl[LINELEN / 2 + 1];
        !           375:        char args[LINELEN];
        !           376:        extern char **environ;
        !           377:        char *index();
        !           378: 
        !           379:        ap = argl;
        !           380:        p = args;
        !           381:        *ap++ = symfile.name;
        !           382:        do {
        !           383:                switch (c = rdc()) {
        !           384: 
        !           385:                case '\n':
        !           386:                        break;
        !           387: 
        !           388:                case '<':
        !           389:                        setfile(0, O_RDONLY, 0, p, "open");
        !           390:                        break;
        !           391: 
        !           392:                case '>':
        !           393:                        setfile(1, O_CREAT|O_WRONLY, 0666, p, "create");
        !           394:                        break;
        !           395: 
        !           396:                default:
        !           397:                        *ap = p;
        !           398:                        while (index(separators, c) == NULL) {
        !           399:                                *p++ = c;
        !           400:                                c = readchar();
        !           401:                        }
        !           402:                        *p++ = '\0';
        !           403:                        ap++;
        !           404:                }
        !           405:        } while (c != '\n');
        !           406:        unreadc();
        !           407:        *ap++ = 0;
        !           408:        execve(symfile.name, argl, environ);
        !           409:        perror(symfile.name);
        !           410: }
        !           411: 
        !           412: static int
        !           413: setfile(fd, flags, mode, namebuf, err)
        !           414:        int fd, flags, mode;
        !           415:        char *namebuf, *err;
        !           416: {
        !           417:        register char *p = namebuf;
        !           418:        register int c = rdc();
        !           419: 
        !           420:        while (index(separators, c) == NULL) {
        !           421:                *p++ = c;
        !           422:                c = readchar();
        !           423:        }
        !           424:        *p = 0;
        !           425:        (void) close(fd);
        !           426:        if (open(namebuf, flags, mode) < 0) {
        !           427:                adbprintf("%s: cannot %s\n", namebuf, err);
        !           428:                _exit(0);
        !           429:                /* NOTREACHED */
        !           430:        }
        !           431: }
        !           432: 
        !           433: struct bkpt *
        !           434: scanbkpt(a)
        !           435:        register addr_t a;
        !           436: {
        !           437:        register struct bkpt *bp;
        !           438: 
        !           439:        for (bp = bkpthead; bp != NULL; bp = bp->next)
        !           440:                if (bp->state != BKPT_FREE && bp->loc == a)
        !           441:                        break;
        !           442:        return (bp);
        !           443: }
        !           444: 
        !           445: bpwait()
        !           446: {
        !           447:        register int w;
        !           448:        union wait status;
        !           449: 
        !           450:        (void) signal(SIGINT, SIG_IGN);
        !           451:        while ((w = wait(&status)) != pid && w != -1)
        !           452:                 /* void */ ;
        !           453:        (void) signal(SIGINT, intcatch);
        !           454:        if (w == -1) {
        !           455:                pid = 0;
        !           456:                errflag = BADWAIT;
        !           457:        } else if (!WIFSTOPPED(status)) {
        !           458:                sigcode = 0;
        !           459:                if ((signo = status.w_termsig) != 0)
        !           460:                        sigprint();
        !           461:                if (status.w_coredump) {
        !           462:                        prints(" - core dumped");
        !           463:                        (void) close(corefile.fd);
        !           464:                        setcore();
        !           465:                }
        !           466:                pid = 0;
        !           467:                bpstate = BPOUT;
        !           468:                errflag = ENDPCS;
        !           469:        } else {
        !           470:                signo = status.w_stopsig;
        !           471:                sigcode = ptrace(PT_READ_U, pid,
        !           472:                                 &((struct user *)0)->u_code, 0); /* XXX */
        !           473:                if (signo != SIGTRAP)
        !           474:                        sigprint();
        !           475:                else
        !           476:                        signo = 0;
        !           477:                flushbuf();
        !           478:        }
        !           479: }

unix.superglobalmegacorp.com

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