Annotation of coherent/b/bin/db/db1.c, revision 1.1.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.