Annotation of coherent/b/bin/db/db1.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * db/db1.c
        !             3:  * A debugger.
        !             4:  * Initialization and command line parsing.
        !             5:  */
        !             6: 
        !             7: #include <stddef.h>
        !             8: #include <canon.h>
        !             9: #include <signal.h>
        !            10: #include <sys/core.h>
        !            11: #include <sys/uproc.h>
        !            12: #include "db.h"
        !            13: 
        !            14: int
        !            15: main(argc, argv) int argc; char *argv[];
        !            16: {
        !            17:        signal(SIGINT, &arm_sigint);
        !            18:        signal(SIGQUIT, SIG_IGN);
        !            19:        initialize();
        !            20:        setup(argc, argv);
        !            21:        process();
        !            22: }
        !            23: 
        !            24: /*
        !            25:  * Catch and flag interrupts (SIGINT).
        !            26:  */
        !            27: void
        !            28: arm_sigint()
        !            29: {
        !            30:        signal(SIGINT, &arm_sigint);
        !            31:        intflag++;
        !            32: }
        !            33: 
        !            34: /*
        !            35:  * Canonicalize an l.out header.
        !            36:  */
        !            37: void
        !            38: canlout()
        !            39: {
        !            40:        register int i;
        !            41: 
        !            42:        canint(ldh.l_magic);
        !            43:        canint(ldh.l_flag);
        !            44:        canint(ldh.l_machine);
        !            45:        canvaddr(ldh.l_entry);
        !            46:        for (i=0; i<NLSEG; i++)
        !            47:                cansize(ldh.l_ssize[i]);
        !            48: }
        !            49: 
        !            50: /*
        !            51:  * Initialize segment formats, clear the breakpoint table,
        !            52:  * invalidate the child process register image.
        !            53:  */
        !            54: void
        !            55: initialize()
        !            56: {
        !            57:        init_mch();
        !            58:        strcpy(seg_format[DSEG], "w");          /* patched in set_prog() if COFF */
        !            59:        strcpy(seg_format[ISEG], "i");
        !            60:        strcpy(seg_format[USEG], "w");          /* patched in set_prog() if COFF */
        !            61:        bpt_init();
        !            62:        reg_flag = R_INVALID;
        !            63: }
        !            64: 
        !            65: /*
        !            66:  * Leave.
        !            67:  */
        !            68: void
        !            69: leave()
        !            70: {
        !            71:        killc();
        !            72:        exit(0);
        !            73: }
        !            74: 
        !            75: /*
        !            76:  * Open the given file.
        !            77:  * If 'rflag' is set, the file is opened for read only.
        !            78:  */
        !            79: FILE *
        !            80: openfile(name, rflag) char *name; int rflag;
        !            81: {
        !            82:        register FILE *fp;
        !            83: 
        !            84: #if    __I386__
        !            85: again:
        !            86: #endif
        !            87:        if (!rflag && (fp = fopen(name, "r+w")) != (FILE *)NULL)
        !            88:                return fp;
        !            89:        else if ((fp = fopen(name, "r")) != (FILE *)NULL) {
        !            90:                if (!rflag)
        !            91:                        printr("%s: opened read only", name);
        !            92:                return fp;
        !            93:        }
        !            94: #if    __I386__
        !            95:        if (strcmp(name, DEFLT_OBJ) == 0) {
        !            96:                name = DEFLT_OBJ2;      /* l.out not found, try a.out */
        !            97:                goto again;
        !            98:        }
        !            99: #endif
        !           100:        panic("Cannot open %s", name);
        !           101: }
        !           102: 
        !           103: /*
        !           104:  * Set up segmentation for a core dump.
        !           105:  * The registers are also read.
        !           106:  * hal improved the core file format 4/93 for COHERENT V4.0.1r75.
        !           107:  * Compiling without -DOLD_CORE builds db which groks only the new format.
        !           108:  * Compiling with -DOLD_CORE builds db which groks both old and new formats.
        !           109:  * This hack should disappear when the old format becomes irrelevant.
        !           110:  */
        !           111: void
        !           112: set_core(name) char *name;
        !           113: {
        !           114:        struct ch_info ch_info;
        !           115:        long offset;
        !           116:        register unsigned i;
        !           117:        register char *cp;
        !           118:        register ADDR_T size;
        !           119:        register off_t offt;
        !           120:        ADDR_T regl;            /* an address, int * in <sys/uproc.h> */
        !           121:        int iflag, textflag;
        !           122:        int signo;
        !           123:        char ucomm[U_COMM_LEN+1];
        !           124:        SR usegs[NUSEG];
        !           125: 
        !           126:        /* Open the core file. */
        !           127:        cfn = name;
        !           128:        cfp = openfile(name, rflag);
        !           129: 
        !           130:        /* Read the core file header and set uproc offset. */
        !           131:        if (fread(&ch_info, sizeof ch_info, 1, cfp) != 1)
        !           132:                panic("Cannot read core file header");
        !           133: #if    !OLD_CORE
        !           134:        if (ch_info.ch_magic != CORE_MAGIC)
        !           135:                panic("Not a core file");
        !           136:        offset = ch_info.ch_info_len + ch_info.ch_uproc_offset;
        !           137: #else
        !           138:        if (ch_info.ch_magic == CORE_MAGIC)
        !           139:                offset = ch_info.ch_info_len + ch_info.ch_uproc_offset;
        !           140:        else
        !           141:                offset = (long)U_OFFSET;
        !           142: #endif
        !           143: 
        !           144:        /* Read the file name from the core file. */
        !           145:        if (fseek(cfp, offset+offsetof(UPROC, u_comm[0]), SEEK_SET) != -1
        !           146:         && (cp = lfn) != NULL
        !           147:         && fread(ucomm, sizeof(ucomm), 1, cfp) == 1) {
        !           148: 
        !           149:                /* Compare object filename to core filename. */
        !           150:                while (strchr(cp, '/') != NULL)
        !           151:                        cp = strchr(cp, '/') + 1;       /* skip past '/' */
        !           152:                if (strncmp(cp, ucomm, sizeof(ucomm)) != 0) {
        !           153:                        ucomm[U_COMM_LEN] = '\0';
        !           154:                        printr("Core file name \"%s\" different from object file name \"%s\"",
        !           155:                                ucomm, lfn);
        !           156:                }
        !           157:        }
        !           158: 
        !           159:        /* Read the core file segment information. */
        !           160:        if (fseek(cfp, offset+offsetof(UPROC, u_segl[0]), SEEK_SET) == -1
        !           161:         || fread(usegs, sizeof(usegs), 1, cfp) != 1)
        !           162:                panic("Bad core file");
        !           163: 
        !           164:        /* Read the core file signal number and register pointer. */
        !           165:        if (fseek(cfp, offset+offsetof(UPROC, u_signo), SEEK_SET) == -1
        !           166:         || fread(&signo, sizeof(signo), 1, cfp) != 1)
        !           167:                panic("cannot read signo");
        !           168:        dbprintf(("signo=%d\n", signo));
        !           169:        if (fread(&regl, sizeof(regl), 1, cfp) != 1)
        !           170:                panic("cannot read regl");
        !           171:        regl &= (NBPC - 1);
        !           172: #if    OLD_CORE
        !           173:        if (ch_info.ch_magic == CORE_MAGIC)
        !           174:                regl += ch_info.ch_info_len;
        !           175: #else
        !           176:        regl += ch_info.ch_info_len;
        !           177: #endif
        !           178:        dbprintf(("regl=%d\n", regl));
        !           179: 
        !           180: #if    __I386__
        !           181:        /* Adjust the i386 stack segment base. */
        !           182:        usegs[SISTACK].sr_base -= usegs[SISTACK].sr_size;
        !           183:        dbprintf(("adjust usegs[SISTACK].sr_base to %x\n", usegs[SISTACK].sr_base));
        !           184: #endif
        !           185: 
        !           186:        /*
        !           187:         * The new core dump format might or might not include the text segment
        !           188:         * but does not include a flag stating if it has been dumped (oops);
        !           189:         * this decides if text is present/absent by adding up segment sizes.
        !           190:         * Presumably it should be setting SRFDUMP flag correctly instead...
        !           191:         */
        !           192:        textflag = 0;
        !           193: #if    OLD_CORE
        !           194:        if (ch_info.ch_magic == CORE_MAGIC) {
        !           195: #endif
        !           196:                offt = usegs[0].sr_size + ch_info.ch_info_len;
        !           197:                for (i=1; i<NUSEG; i++) {
        !           198:                        if (usegs[i].sr_segp == (SEG *)NULL)
        !           199:                                continue;
        !           200:                        if ((~usegs[i].sr_flag) & (SRFDUMP|SRFPMAP))
        !           201:                                continue;
        !           202:                        offt += usegs[i].sr_size;
        !           203:                }
        !           204:                fseek(cfp, 0L, SEEK_END);
        !           205:                textflag = (ftell(cfp) != offt);
        !           206:                dbprintf(("cfp_len=%lx offt=%lx textflag=%d", ftell(cfp), offt, textflag));
        !           207: #if    OLD_CORE
        !           208:        }
        !           209: #endif
        !           210: 
        !           211:        /* Set up segmentation. */
        !           212:        iflag = ISPACE == DSPACE;
        !           213:        map_set(USEG, MIN_ADDR, (ADDR_T)UPASIZE, (off_t)regl, MAP_CORE);
        !           214:        map_clear(DSEG, endpure);
        !           215:        offt = usegs[0].sr_size;
        !           216: #if    OLD_CORE
        !           217:        if (ch_info.ch_magic == CORE_MAGIC)
        !           218:                offt += ch_info.ch_info_len;
        !           219: #else
        !           220:        offt += ch_info.ch_info_len;
        !           221: #endif
        !           222:        if (textflag) {
        !           223:                /* Map the text segment. */
        !           224:                map_clear(ISEG, NULL);
        !           225:                size = usegs[SISTEXT].sr_size;
        !           226:                map_set(ISEG, (ADDR_T)usegs[SISTEXT].sr_base, size, offt, MAP_CORE);
        !           227:                offt += size;
        !           228:        }
        !           229:        for (i=1; i<NUSEG; i++) {
        !           230:                if (usegs[i].sr_segp == (SEG *)NULL)
        !           231:                        continue;
        !           232:                if ((~usegs[i].sr_flag) & (SRFDUMP|SRFPMAP))
        !           233:                        continue;
        !           234:                size = usegs[i].sr_size;
        !           235:                map_set(DSEG, (ADDR_T)usegs[i].sr_base, size, offt, MAP_CORE);
        !           236:                offt += size;
        !           237:        }
        !           238:        if (iflag)
        !           239:                ISPACE = DSPACE;
        !           240:        get_regs(R_ALL);                        /* read the registers */
        !           241:        if (!rflag)
        !           242:                set_sig(signo);                 /* correct signal number */
        !           243: }
        !           244: 
        !           245: /*
        !           246:  * Set up segmentation for an ordinary file.
        !           247:  * This is really easy.
        !           248:  */
        !           249: void
        !           250: set_file(name) char *name;
        !           251: {
        !           252:        lfp = openfile(name, rflag);
        !           253:        map_set(DSEG, MIN_ADDR, MAX_ADDR, (off_t)0, MAP_PROG);
        !           254:        ISPACE = DSPACE;
        !           255: }
        !           256: 
        !           257: /*
        !           258:  * Setup object file "name".
        !           259:  * The flag is bit mapped:
        !           260:  *     1 bit   read symbol table
        !           261:  *     2 bit   read segment information
        !           262:  */
        !           263: void
        !           264: set_prog(name, flag) char *name; int flag;
        !           265: {
        !           266:        dbprintf(("set_prog(%s, %d)\n", name, flag));
        !           267:        lfp = openfile(name, (flag&2) ? rflag : 1);
        !           268:        if (fread(&coff_hdr, sizeof(coff_hdr), 1, lfp) != 1)
        !           269:                panic("Cannot read object file header");
        !           270:        if (coff_hdr.f_magic == C_386_MAGIC) {
        !           271:                /* The object is a COFF file. */
        !           272:                dbprintf(("IS_COFF!\n"));
        !           273:                file_type = COFF_FILE;
        !           274:                addr_fmt = ADDR_FMT;
        !           275:                aop_size = 32;
        !           276:                strcpy(seg_format[DSEG], "l");
        !           277:                strcpy(seg_format[USEG], "l");
        !           278:        } else {
        !           279:                /* Not a COFF file, might be an l.out. */
        !           280:                if (fseek(lfp, 0L, SEEK_SET) == -1
        !           281:                 || fread(&ldh, sizeof(ldh), 1, lfp) != 1)
        !           282:                        panic("Cannot read object file");
        !           283:                canlout();
        !           284:                if (ldh.l_magic != L_MAGIC)
        !           285:                        panic("Bad object file");
        !           286: 
        !           287:                /* The object is an l.out file. */
        !           288:                dbprintf(("IS_LOUT!\n"));
        !           289:                file_type = LOUT_FILE;
        !           290:                addr_fmt = ADDR16_FMT;
        !           291:                aop_size = 16;
        !           292:        }
        !           293:        if ((flag&1) != 0 && !sflag) {
        !           294:                sfp = lfp;
        !           295:                if (IS_LOUT) {
        !           296:                        nsyms = ldh.l_ssize[L_SYM] / sizeof(struct ldsym);
        !           297:                        if (nsyms != 0)
        !           298:                                read_lout_sym((long) sizeof(ldh)
        !           299:                                         + ldh.l_ssize[L_SHRI] + ldh.l_ssize[L_PRVI]
        !           300:                                         + ldh.l_ssize[L_SHRD] + ldh.l_ssize[L_PRVD]);
        !           301:                } else {
        !           302:                        if (coff_hdr.f_nsyms != 0)
        !           303:                                read_coff_sym();
        !           304:                }
        !           305:        }
        !           306:        if ((flag&2) != 0) {
        !           307:                lfn = name;
        !           308:                if (IS_LOUT)
        !           309:                        setloutseg();
        !           310:                else
        !           311:                        setcoffseg();
        !           312:        }
        !           313: }
        !           314: 
        !           315: /*
        !           316:  * Setup arguments.
        !           317:  */
        !           318: void
        !           319: setup(argc, argv) int argc; char *argv[];
        !           320: {
        !           321:        register char *cp;
        !           322:        register int c;
        !           323:        register int t;
        !           324:        register int u;
        !           325:        register int tflag;
        !           326: 
        !           327:        t = '\0';
        !           328:        tflag = 0;
        !           329: 
        !           330:        /* Process command line switches -[cdefkorstV]. */
        !           331:        for (; argc > 1; argc--, argv++) {
        !           332:                cp = argv[1];
        !           333:                if (*cp++ != '-')
        !           334:                        break;
        !           335:                while ((c = *cp++) != '\0') {
        !           336:                        switch (c) {
        !           337:                        case 'c':
        !           338:                        case 'd':
        !           339:                        case 'e':
        !           340:                        case 'f':
        !           341:                        case 'k':
        !           342:                        case 'o':
        !           343:                                /* only one of [cdefko] is allowed */
        !           344:                                if (t != '\0')
        !           345:                                        usage();
        !           346:                                t = c;
        !           347:                                continue;
        !           348:                        case 'p':
        !           349:                                if (argc < 3)
        !           350:                                        usage();
        !           351:                                --argc;
        !           352:                                prompt = argv[2];
        !           353:                                ++argv;
        !           354:                                continue;
        !           355:                        case 'r':
        !           356:                                rflag = 1;
        !           357:                                continue;
        !           358:                        case 's':
        !           359:                                sflag = 1;
        !           360:                                continue;
        !           361:                        case 't':
        !           362:                                tflag = 1;
        !           363:                                continue;
        !           364:                        case 'V':
        !           365:                                fprintf(stderr,
        !           366:                                        "db: " MCHNAME " "
        !           367: #if    DEBUG
        !           368:                                        "DEBUG "
        !           369: #endif
        !           370: #ifdef NOCANON
        !           371:                                /*      "NOCANON "      */
        !           372: #endif
        !           373: #ifdef NOFP
        !           374:                                        "NOFP "
        !           375: #endif
        !           376:                                        "V%s\n", VERSION);
        !           377:                                continue;
        !           378:                        default:
        !           379:                                usage();
        !           380:                        }
        !           381:                }
        !           382:        }
        !           383:        switch (t) {
        !           384:        case '\0':
        !           385:                switch (argc) {
        !           386:                case 1:
        !           387:                        set_prog(DEFLT_OBJ, 3);
        !           388:                        set_core(DEFLT_AUX);
        !           389:                        break;
        !           390:                case 2:
        !           391:                        set_prog(argv[1], 3);
        !           392:                        break;
        !           393:                case 3:
        !           394:                        set_prog(argv[1], 3);
        !           395:                        set_core(argv[2]);
        !           396:                        break;
        !           397:                default:
        !           398:                        usage();
        !           399:                }
        !           400:                break;
        !           401:        case 'c':
        !           402:                switch (argc) {
        !           403:                case 1:
        !           404:                        set_prog(DEFLT_OBJ, 3);
        !           405:                        set_core(DEFLT_AUX);
        !           406:                        break;
        !           407:                case 2:
        !           408:                        set_core(argv[1]);
        !           409:                        break;
        !           410:                case 3:
        !           411:                        set_prog(argv[1], 3);
        !           412:                        set_core(argv[2]);
        !           413:                        break;
        !           414:                default:
        !           415:                        usage();
        !           416:                }
        !           417:                break;
        !           418:        case 'd':
        !           419:                switch (argc) {
        !           420:                case 1:
        !           421:                        set_prog("/coherent", 3);
        !           422:                        setdump("/dev/dump");
        !           423:                        break;
        !           424:                case 3:
        !           425:                        set_prog(argv[1], 3);
        !           426:                        setdump(argv[2]);
        !           427:                        break;
        !           428:                default:
        !           429:                        usage();
        !           430:                }
        !           431:                break;
        !           432:        case 'e':
        !           433:                if (argc < 2)
        !           434:                        usage();
        !           435:                set_prog(argv[1], 3);
        !           436:                if (startc(&argv[1], NULL, NULL, 0) == 0)
        !           437:                        leave();
        !           438:                break;
        !           439:        case 'f':
        !           440:                switch (argc) {
        !           441:                case 2:
        !           442:                        set_file(argv[1]);
        !           443:                        break;
        !           444:                case 3:
        !           445:                        set_prog(argv[1], 1);
        !           446:                        set_file(argv[2]);
        !           447:                        break;
        !           448:                default:
        !           449:                        usage();
        !           450:                }
        !           451:                break;
        !           452:        case 'k':
        !           453:                switch (argc) {
        !           454:                case 1:
        !           455:                        set_prog("/coherent", 1);
        !           456:                        setkmem("/dev/mem");
        !           457:                        break;
        !           458:                case 2:
        !           459:                        setkmem(argv[1]);
        !           460:                        break;
        !           461:                case 3:
        !           462:                        set_prog(argv[1], 1);
        !           463:                        setkmem(argv[2]);
        !           464:                        break;
        !           465:                default:
        !           466:                        usage();
        !           467:                }
        !           468:                break;
        !           469:        case 'o':
        !           470:                switch (argc) {
        !           471:                case 1:
        !           472:                        set_prog(DEFLT_OBJ, 3);
        !           473:                        break;
        !           474:                case 2:
        !           475:                        set_prog(argv[1], 3);
        !           476:                        break;
        !           477:                case 3:
        !           478:                        set_prog(argv[1], 1);
        !           479:                        set_prog(argv[2], 2);
        !           480:                        break;
        !           481:                default:
        !           482:                        usage();
        !           483:                }
        !           484:        }
        !           485:        if (tflag) {
        !           486:                if ((u=open("/dev/tty", 2)) < 0)
        !           487:                        panic("Cannot open /dev/tty");
        !           488:                dup2(u, 0);
        !           489:                dup2(u, 1);
        !           490:                dup2(u, 2);
        !           491:        }
        !           492: }
        !           493: 
        !           494: /*
        !           495:  * Check for interrupts and clear flag.
        !           496:  */
        !           497: int
        !           498: testint()
        !           499: {
        !           500:        register int n;
        !           501: 
        !           502:        if ((n = intflag) != 0) {
        !           503:                printf("Interrupted\n");
        !           504:                intflag = 0;
        !           505:        }
        !           506:        return n;
        !           507: }
        !           508: 
        !           509: /*
        !           510:  * Generate a verbose usage message.
        !           511:  */
        !           512: void
        !           513: usage()
        !           514: {
        !           515:        panic(
        !           516:                "Usage: db [ -cdefkorst ] [ [ mapfile ] program ]\n"
        !           517:                "Options:\n"
        !           518:                "\t-c\tprogram is a core file\n"
        !           519:                "\t-d\tprogram is a system dump; mapfile defaults to /coherent\n"
        !           520:                "\t-e\tNext argument is object file and rest of command line is passed\n"
        !           521:                "\t\tto the child process\n"
        !           522:                "\t-f\tprogram is binary data (an ordinary file)\n"
        !           523:                "\t-k\tprogram is a kernel process; mapfile defaults to /coherent\n"
        !           524:                "\t-o\tprogram is an object file\n"
        !           525:                "\t-p str\tUse str as interactive command prompt (default: \"db: \")\n"
        !           526:                "\t-r\tAccess all files read-only\n"
        !           527:                "\t-s\tDo not load symbol table\n"
        !           528:                "\t-t\tPerform input and output via /dev/tty\n"
        !           529:                "\tmapfile defaults to a.out or l.out.\n"
        !           530:                "\tprogram defaults to core.\n"
        !           531:                "Examples:\n"
        !           532:                "\tdb prog\t\tExamine, patch, execute \"prog\" under db control\n"
        !           533:                "\tdb prog core\tExamine postmortem core dump \"core\",\n"
        !           534:                "\t\t\tusing symbol table from \"prog\"\n"
        !           535:                "\tdb -e prog *.c\tExecute \"prog\" under db control with args *.c\n"
        !           536:                "\tdb -f file\tExamine and patch \"file\" as stream of bytes\n"
        !           537:        );
        !           538: }
        !           539: 
        !           540: /* end of db/db1.c */

unix.superglobalmegacorp.com

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