Annotation of 3BSD/cmd/sdb/symt.c, revision 1.1.1.1

1.1       root        1: #include "head.h"
                      2: #include <a.out.h>
                      3: #include <sys/stat.h>
                      4: 
                      5: struct user u;
                      6: int compar();
                      7: char *symfil;
                      8: 
                      9: /* initialize file and procedure tables */
                     10: initfp() {
                     11:        struct nlist stentry;
                     12:        register struct proct *procp;
                     13:        register struct filet *filep;
                     14:        struct stat stbuf;
                     15: 
                     16:        long soffset;
                     17:        int i;
                     18:        char class;
                     19:        register char *p, *q;
                     20:        
                     21:        sbuf.fd = txtmap.ufd;
                     22:        soffset = ststart;
                     23:        blseek(&sbuf,ststart,0);
                     24:        filep = files = badfile = (struct filet *) sbrk(sizeof filep[0]);
                     25:        procp = procs = badproc = (struct proct *) sbrk(sizeof procp[0]);
                     26:        
                     27:        for(;;) {
                     28:                if (bread(&sbuf, &stentry, sizeof stentry) <
                     29:                                sizeof stentry) break;
                     30:                class = stentry.n_type & STABMASK;
                     31:                switch (class & STABMASK) {
                     32:                case N_SO:
                     33:                case N_SOL:
                     34:                        if (filep == badfile) {
                     35:                                p = sbrk(FILEINCR*sizeof filep[0]);
                     36:                                if (p < 0) {
                     37:                                        perror("sdb");
                     38:                                        exit(4);
                     39:                                }
                     40:                                q = p + FILEINCR*sizeof filep[0];
                     41:                                while (p > (char *) procs)
                     42:                                        *--q = *--p;
                     43:                                badfile += FILEINCR;
                     44:                                procp = (struct proct *)
                     45:                                    ((char *) procp +
                     46:                                                FILEINCR*sizeof filep[0]);
                     47:                                procs = (struct proct *)
                     48:                                    ((char *) procs +
                     49:                                                FILEINCR*sizeof filep[0]);
                     50:                                badproc = (struct proct *)
                     51:                                    ((char *)badproc +
                     52:                                                FILEINCR*sizeof filep[0]);
                     53:                        }
                     54:                        filep->faddr = stentry.n_value;
                     55:                        filep->lineflag = (class == N_SOL);
                     56:                        filep->stf_offset = soffset;
                     57:                        p = filep->sfilename;
                     58:                        for (;;) {
                     59:                                for (i=0; i<8; i++) *p++ = stentry.n_name[i];
                     60:                                if (*(p-1) == '\0') break;
                     61:                                if (bread(&sbuf, &stentry, sizeof stentry) 
                     62:                                                < sizeof stentry)
                     63:                                        error("Bad N_SO entry (1)");
                     64:                                if ((stentry.n_type & STABMASK) !=
                     65:                                                (unsigned char) class)
                     66:                                        error("Bad N_SO entry (2)");
                     67:                                soffset += sizeof stentry;
                     68:                        }
                     69:                        q = filep->sfilename;
                     70:                        for (p=fp; *q; *p++ = *q++) ;
                     71:                        *p = 0;
                     72:                        if (stat(filework, &stbuf) == -1)
                     73:                                printf("Warning: `%s' not found\n",
                     74:                                        filep->sfilename);
                     75:                        else if (stbuf.st_mtime > symtime)
                     76:                                printf("Warning: `%s' newer than `%s'\n",
                     77:                                        filep->sfilename,
                     78:                                        symfil);
                     79:                        filep++;
                     80:                        break;
                     81:                        
                     82:                case N_TEXT:
                     83:                        if (stentry.n_name[0] != '_') break;
                     84:                case N_FUN:
                     85:                case N_ENTRY:
                     86:                        if (procp == badproc) {
                     87:                                if (sbrk(PROCINCR*sizeof procp[0]) < 0) {
                     88:                                        perror("sdb");
                     89:                                        exit(4);
                     90:                                }
                     91:                                badproc += PROCINCR;
                     92:                        }
                     93:                        for(i=0; i<8; i++)
                     94:                                procp->pname[i] = stentry.n_name[i];
                     95:                        procp->paddr = stentry.n_value;
                     96:                        procp->st_offset = soffset;
                     97:                        procp->sfptr = (class != N_TEXT) ? filep - 1 : badfile;
                     98:                        procp->lineno = (class != N_TEXT) ? stentry.n_desc : 0;
                     99:                        procp->entrypt = (class & STABMASK) == N_ENTRY;
                    100:                        procp++;
                    101:                        break;
                    102:                }
                    103:                if (stentry.n_type & N_EXT  &&  !extstart) {
                    104:                        extstart = soffset;
                    105:                }
                    106:                soffset += sizeof stentry;
                    107:        }
                    108:        qsort(procs, procp-procs, sizeof procs[0], compar);
                    109:        badproc->st_offset = soffset;
                    110:        badproc->sfptr = procp->sfptr = badfile;
                    111:        badproc->pname[0] = badfile->sfilename[0]=
                    112:                procp->pname[0] = filep->sfilename[0] = '\0';
                    113: 
                    114:        setcur(1);
                    115: }
                    116: 
                    117: /* returns current procedure from state (curfile, fline) */
                    118: struct proct *
                    119: curproc() {
                    120:        register ADDR addr;
                    121: 
                    122:        addr = getaddr("", fline);
                    123:        if (addr == -1) return(badproc);
                    124:        return(adrtoprocp(addr));
                    125: 
                    126: }
                    127: 
                    128: /* returns procedure s, uses curproc() if s == NULL */
                    129: 
                    130: struct proct *
                    131: findproc(s)
                    132: char *s; {
                    133:        register struct proct *p;
                    134:        
                    135:        if (s[0] == '\0') return(curproc());
                    136:        
                    137:        for(p=procs; p->pname[0]; p++)
                    138:                if (eqstr(p->pname, s)) return(p);
                    139:                
                    140:        if (debug) printf("%s(): unknown name\n", s);
                    141:        return(badproc);
                    142: }
                    143: 
                    144: /* returns file s containing filename */
                    145: struct filet *
                    146: findfile(s)
                    147: char *s; {
                    148:        register struct filet *f;
                    149:        for (f=files; f->sfilename[0]; f++) {
                    150:                if (eqstr(f->sfilename, s)) { 
                    151:                        for( ; f->lineflag; f--) ;
                    152:                        if (f < files) error("Bad file array");
                    153:                        return(f);
                    154:                }
                    155:        }
                    156:        return(f);
                    157: }
                    158: 
                    159: /*
                    160:  * slookup():
                    161:  * looks up variable matching pat starting at offset in a.out, searching
                    162:  * backwards, ignoring nested blocks to beginning to procedure.
                    163:  * Returns its offset and symbol table entries decoded in sl_*
                    164:  *
                    165:  * If comblk == "*" then match both within and outside common blocks,
                    166:  * if comblk == ""  then match only outside common blocks,
                    167:  *                  else match only within comblk.
                    168:  */
                    169:  
                    170: long
                    171: slookup(pat, poffset, stelt)
                    172: long poffset; char *pat; {
                    173:        slookinit();
                    174:        slooknext(pat, poffset, stelt, "*");
                    175: }
                    176: 
                    177: int clevel, level, fnameflag, comfound, incomm;
                    178: 
                    179: slookinit() {
                    180:        clevel = level = fnameflag = comfound = incomm = 0;
                    181: }
                    182: 
                    183: long
                    184: slooknext(pat, poffset, stelt, comblk)
                    185: long poffset; char *pat, *comblk; {
                    186:        register int i;
                    187:        register long offset;
                    188:        char class, *q;
                    189:        struct nlist stentry;
                    190:        struct proct *procp, *p;
                    191:        
                    192:        offset = poffset + sizeof stentry;
                    193:        if (debug) printf("slookup(%s,%d)\n",pat,offset);
                    194:        blseek(&sbuf, offset, 0);
                    195:        
                    196:        for (;;) {
                    197:                offset -= sizeof stentry;
                    198:                if (offset < ststart) break;
                    199:                if (bread(&sbuf, &stentry+1, -sizeof stentry) 
                    200:                        < sizeof stentry) break;
                    201:                class = stentry.n_type & STABMASK;
                    202:                switch (class & STABMASK) {
                    203:                case 0:
                    204:                        break;
                    205:                case N_FUN:
                    206:                        return(-1);
                    207:                case N_RBRAC:
                    208:                        level++;
                    209:                        break;
                    210:                case N_LBRAC:
                    211:                        level--;
                    212:                        break;
                    213:                case N_ECOMM:
                    214:                        for (q = &stentry.n_name[7]; q>=stentry.n_name; q--) {
                    215:                                if (*q == '_') {
                    216:                                        *q = '\0';
                    217:                                        break;
                    218:                                }
                    219:                        }
                    220:                        if (eqpat(comblk, stentry.n_name))
                    221:                                comfound = 1;
                    222:                        incomm = 1;
                    223:                case N_ECOML:
                    224:                        clevel++;
                    225:                        break;
                    226:                case N_BCOMM:
                    227:                        comfound = incomm = 0;
                    228:                        clevel--;
                    229:                        break;
                    230:                case N_FNAME:
                    231:                        if (fnameflag)
                    232:                                break;
                    233:                        procp = findproc(stentry.n_name);
                    234:                        for (p=procs; p->pname[0]; p++) {
                    235:                                if (p->entrypt == 0 &&
                    236:                                        p->st_offset > procp->st_offset &&
                    237:                                        p->st_offset < offset)
                    238:                                                offset = p->st_offset;
                    239:                        }
                    240:                        clevel = level = 0;
                    241:                        fnameflag++;
                    242:                        blseek(&sbuf, offset, 0);
                    243:                        break;
                    244:                default:
                    245:                        if (level <= 0  &&  eqpat(pat, stentry.n_name) &&
                    246:                                stentry.n_name[0] && class & STABTYPES &&
                    247:                                (eqstr("*", comblk) ||
                    248:                                 (comblk[0] == '\0' && incomm == 0) ||
                    249:                                 comfound) &&
                    250:                                (stelt == (class == N_SSYM))) {
                    251:                                if (class == N_LENG) {
                    252:                                        sl_size = stentry.n_value;
                    253:                                        offset -= sizeof stentry;
                    254:                                        bread(&sbuf, &stentry+1,
                    255:                                                        -sizeof stentry);
                    256:                                }
                    257:                                else sl_size = 0;
                    258:                                sl_class = stentry.n_type & STABMASK;
                    259:                                sl_type = stentry.n_desc;
                    260:                                sl_addr = stentry.n_value;
                    261:                                for (i=0; i<8; i++) sl_name[i] =
                    262:                                                stentry.n_name[i];
                    263:                                if (clevel != 0) docomm(offset);
                    264:                                return(offset - sizeof stentry);
                    265:                        }
                    266:                }
                    267:        }
                    268:        return(-1);
                    269: }
                    270: 
                    271: /* 
                    272:  * Look up global variable matching pat
                    273:  * Return its offset and symbol table entries decoded in sl_*
                    274:  */
                    275: long
                    276: globallookup(pat, filestart, stelt)
                    277: char *pat; long filestart; {
                    278:        register int offset, i;
                    279:        struct nlist stentry;
                    280:        int class, clevel;
                    281:        
                    282:        if (debug) printf("globallookup(%s,%d)\n", pat,filestart);
                    283:        blseek(&sbuf, filestart, 0);
                    284:        offset = filestart - sizeof stentry;
                    285:        clevel = 0;
                    286:        do {
                    287:                if (bread(&sbuf, &stentry, sizeof stentry) <
                    288:                                sizeof stentry) return(-1);
                    289:                offset += sizeof stentry;
                    290:        } while ((stentry.n_type & STABMASK) == N_SO);
                    291:        for (;;) {
                    292:                class = stentry.n_type & STABMASK;
                    293:                switch (class & STABMASK) {
                    294:                case N_SO:
                    295:                        return(-1);
                    296:                case N_ECOMM:
                    297:                        clevel--;
                    298:                        break;
                    299:                case N_BCOMM:
                    300:                        clevel++;
                    301:                        break;
                    302:                default:
                    303:                if (eqpat(pat, stentry.n_name) 
                    304:                                && stentry.n_name[0] && class & STABTYPES) {
                    305:                        sl_class = stentry.n_type & STABMASK;
                    306:                        if (sl_class != N_GSYM && sl_class != N_SSYM && 
                    307:                                sl_class != N_STSYM) goto g1;
                    308:                        if (stelt != (sl_class == N_SSYM)) goto g1;
                    309:                        sl_size = 0;
                    310:                        sl_type = stentry.n_desc;
                    311:                        sl_addr = stentry.n_value;
                    312:                        for (i=0; i<8; i++) sl_name[i] = stentry.n_name[i];
                    313:                        if (clevel != 0) docomm(offset);
                    314:                        goto g2;
                    315:                }
                    316:                }
                    317: g1:            if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry)
                    318:                        return(-1);
                    319:                offset += sizeof stentry;
                    320:        }
                    321: g2:    bread(&sbuf, &stentry, sizeof stentry);
                    322:        if (((stentry.n_type & STABMASK) == N_LENG) &&
                    323:                        (eqpat(sl_name, stentry.n_name)))
                    324:                sl_size = stentry.n_value;
                    325: 
                    326:        if (sl_class == N_GSYM && (clevel == 0)) {
                    327:                blseek(&sbuf, extstart, 0);
                    328:                for(;;) {
                    329:                        if (bread(&sbuf, &stentry, sizeof stentry) 
                    330:                                        < sizeof stentry)
                    331:                                return(-1);
                    332:                        if (stentry.n_name[0] != '_') continue;
                    333:                        if (eqpatr(sl_name, stentry.n_name+1, 1)) {
                    334:                                sl_addr = stentry.n_value;
                    335:                                break;
                    336:                        }
                    337:                }
                    338:        }
                    339:        return(offset + sizeof stentry);
                    340: }
                    341: 
                    342: /* core address to procedure (pointer to proc array) */
                    343: struct proct *
                    344: adrtoprocp(addr) 
                    345: ADDR addr; {
                    346:        register struct proct *procp, *lastproc;
                    347:        lastproc = badproc;
                    348:        for (procp=procs; procp->pname[0]; procp++) {
                    349:                if (procp->paddr > addr) break;
                    350:                if (procp->entrypt == 0)
                    351:                        lastproc = procp;
                    352:        }
                    353:        return (lastproc);
                    354: }
                    355:  
                    356: 
                    357: /* core address to file (pointer to file array) */
                    358: struct filet *
                    359: adrtofilep(addr) 
                    360: ADDR addr; {
                    361:        register struct filet *filep;
                    362:        for (filep=files; filep->sfilename[0]; filep++) {
                    363:                if (filep->faddr > addr) break;
                    364:        }
                    365:        return (filep != files ? filep-1 : badfile);
                    366: }
                    367:  
                    368: /* core address to linenumber */
                    369: long lastoffset;
                    370: 
                    371: adrtolineno(addr) 
                    372: ADDR addr; {
                    373:        register int lineno;
                    374:        long offset; 
                    375:        struct nlist stentry;
                    376:        
                    377:        lineno = lastoffset = -1;
                    378:        offset = adrtoproc(addr)->st_offset;
                    379:        blseek(&sbuf, offset, 0);
                    380:        for (;;) {
                    381:                if (bread(&sbuf, &stentry, sizeof stentry) 
                    382:                                < sizeof stentry) break;
                    383:                if (stentry.n_type == N_SLINE) {
                    384:                        if (stentry.n_value > addr) break;
                    385:                        lastoffset = offset;
                    386:                        lineno = stentry.n_desc;
                    387:                }
                    388:                offset += sizeof stentry;
                    389:        }
                    390:        return (lineno);
                    391: }
                    392: 
                    393: 
                    394: /* address to a.out offset */
                    395: long
                    396: adrtostoffset(addr) 
                    397: ADDR addr; {
                    398:        adrtolineno(addr);
                    399:        return(lastoffset);
                    400: }
                    401: 
                    402: 
                    403: /*
                    404:  * Set (curfile, lineno) from core image.
                    405:  * Returns 1 if there is a core image, 0 otherwise.
                    406:  *
                    407:  * Print the current line iff verbose is set.
                    408:  */
                    409: setcur(verbose) {
                    410:        register struct proct *procp;
                    411:        
                    412:        dot = *(ADDR *) (((ADDR) &u) + PC);
                    413:        
                    414:        if (dot == 0) {
                    415:                printf("No core image\n");
                    416:                goto setmain;
                    417:        }
                    418:        procp = adrtoprocp(dot);
                    419:        if ((procp->sfptr) != badfile) {
                    420:                finit(adrtofilep(procp->paddr)->sfilename);
                    421:                ffind(adrtolineno(dot));
                    422:                if (verbose) {
                    423:                        printf("%.8s:", procp->pname);
                    424:                        fprint();
                    425:                }
                    426:                return(1);
                    427:        }
                    428:        if (verbose) {
                    429:                if (procp->pname[0] == '_') 
                    430:                        printf("%.7s: address 0x%x\n", procp->pname+1, dot);
                    431:                else
                    432:                        printf("%.8s: address %d\n", procp->pname, dot);
                    433:        }
                    434:        
                    435: setmain:
                    436:        procp = findproc("MAIN_");
                    437:        if ((procp->pname[0] != 'M') || (procp->sfptr == badfile)) {
                    438:                procp = findproc("main");
                    439:                if ((procp->pname[0] != 'm') || (procp->sfptr == badfile)) {
                    440:                        nolines = 1;
                    441:                        printf("main not compiled with debug flag\n");
                    442:                        return(0);
                    443:                }
                    444:        }
                    445:        finit(procp->sfptr->sfilename);
                    446:        ffind(procp->lineno);
                    447:        return(0);
                    448: }
                    449: 
                    450: compar(a, b)
                    451: struct proct *a, *b; {
                    452:        if (a->paddr == b->paddr) {
                    453:                if (a->pname[0] == '_') return(-1);
                    454:                if (b->pname[0] == '_') return(1);
                    455:                return(0);
                    456:        }
                    457:        return(a->paddr < b->paddr ? -1 : 1);
                    458: }
                    459: 
                    460: /* gets offset of file or procedure named s */
                    461: nametooffset(s)
                    462: char *s; {
                    463:        register struct filet *f;
                    464:        register struct proct *p;
                    465:        
                    466:        if (*s == '\0')
                    467:                return(-1);
                    468:        if (eqany('.', s)) {
                    469:                f = findfile(s);
                    470:                return(f->sfilename[0] ? f->stf_offset : -1);
                    471:        }
                    472:        p = findproc(s);
                    473:        return(p->pname[0] ? p->st_offset : -1);
                    474: }
                    475: /* returns s if its a filename, its file otherwise */
                    476: char *
                    477: nametofile(s)
                    478: char *s; {
                    479:        register struct proct *p;
                    480:        
                    481:        if (eqany('.', s)) {
                    482:                return(s);
                    483:        }
                    484:        p = findproc(s);
                    485:        return(adrtofilep(p->paddr)->sfilename);
                    486: }
                    487: 
                    488: 
                    489: /* line number to address, starting at offset in a.out */
                    490: /* assumes that offset is within file */
                    491: lntoaddr(lineno, offset, file) 
                    492: long offset; char *file; {
                    493:        struct nlist stentry;
                    494:        register int i, ignore = 0;
                    495:        register int bestln=BIGNUM;
                    496:        ADDR bestaddr;
                    497:        char *p;
                    498:        
                    499:        blseek(&sbuf, offset, 0);
                    500:        
                    501:        do {
                    502:                if (bread(&sbuf, &stentry, sizeof stentry) <
                    503:                                sizeof stentry) return(-1);
                    504:        } while ((stentry.n_type & STABMASK) == N_SO);
                    505:        for (;;) {
                    506:                switch(stentry.n_type & STABMASK) {
                    507:                case N_SLINE:
                    508:                        if (!ignore) {
                    509:                                if (stentry.n_desc == lineno)
                    510:                                        return(stentry.n_value);
                    511:                                if (stentry.n_desc > lineno &&
                    512:                                        stentry.n_desc < bestln) {
                    513:                                        bestln = stentry.n_desc;
                    514:                                        bestaddr = stentry.n_value;
                    515:                                }
                    516:                        }
                    517:                        break;
                    518: 
                    519:                case N_SO:
                    520:                        goto ret;
                    521: 
                    522:                case N_SOL:
                    523:                        p = file;
                    524:                        for (;;) {
                    525:                                for (i=0; i<8; i++) {
                    526:                                        if (*p != stentry.n_name[i]) goto neq;
                    527:                                        if (*p++ == '\0') break;
                    528:                                }
                    529:                                if (stentry.n_name[7] == '\0')
                    530:                                        break;
                    531:                                if (bread(&sbuf, &stentry, sizeof stentry) 
                    532:                                                < sizeof stentry)
                    533:                                        error("Bad N_SO entry (1)");
                    534:                                if ((stentry.n_type & STABMASK) != 
                    535:                                                (unsigned char) N_SOL)
                    536:                                        error("Bad N_SO entry (2)");
                    537:                        }
                    538:                        ignore = 0;
                    539:                        break;
                    540: 
                    541: neq:                   ignore++;
                    542:                        break;
                    543:                }
                    544:                if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry) 
                    545:                        break;
                    546:        }
                    547: ret:   return(bestln == BIGNUM ? -1 : bestaddr);
                    548: }
                    549: 
                    550: /* gets address of proc:number */
                    551: getaddr(proc,integ) 
                    552: char *proc; {
                    553:        register long offset;
                    554:        register char *s, *f;
                    555:        ADDR addr;
                    556:        
                    557:        s = proc[0] ? proc : curfile;
                    558:        if (*s == '\0')
                    559:                return(-1);
                    560:        offset = nametooffset(s);
                    561:        f = nametofile(s);
                    562:        if (debug) printf("getaddr() computed offset %d", offset);
                    563:        if (offset == -1) {
                    564:                addr = extaddr(proc);
                    565:                if (addr != -1) addr += 2;  /* MACHINE DEPENDENT */
                    566:                if (debug) printf(" extaddr computed %d\n", addr);
                    567:                return(addr);
                    568:        }
                    569:        if (integ)
                    570:                addr = lntoaddr(integ, offset, s);
                    571:        else {
                    572:                addr = findproc(proc)->paddr + 2;  /* MACHINE DEPENDENT */
                    573:                addr = lntoaddr(adrtolineno(addr)+1, offset, f);
                    574:        }
                    575:        if (debug) printf(" and addr %d\n", addr);
                    576:        if (addr == -1) return(-1);
                    577:        return(addr);
                    578: }
                    579: 
                    580: /* returns address of external */
                    581: ADDR
                    582: extaddr(name)
                    583: char *name; {
                    584:        struct nlist stentry;
                    585:        blseek(&sbuf, extstart, 0);
                    586:        
                    587:        for (;;) {
                    588:                if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry)
                    589:                        return(-1);
                    590:                if (stentry.n_name[0] == '_' && 
                    591:                            eqpatr(name, stentry.n_name+1, 1)) 
                    592:                        return(stentry.n_value);
                    593:        }
                    594: }
                    595: 
                    596: /* find enclosing common blocks and fix up addresses */
                    597: docomm(offset)
                    598: long offset; {
                    599:        struct nlist stentry;
                    600: 
                    601:        for (;;) {
                    602:                if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry) {
                    603:                        error("Bad common block");
                    604:                        return;
                    605:                }
                    606:                sl_class = N_GSYM;
                    607:                if ((stentry.n_type & STABMASK) == N_ECOMM) {
                    608:                        sl_addr += extaddr(stentry.n_name);
                    609:                        blseek(&sbuf, offset, 0);
                    610:                        return;
                    611:                }
                    612:                if ((stentry.n_type & STABMASK) == N_ECOML) {
                    613:                        sl_addr += stentry.n_value;
                    614:                        blseek(&sbuf, offset, 0);
                    615:                        return;
                    616:                }
                    617:        }
                    618: }
                    619: 
                    620: /* determine if class is that of a variable */
                    621: char pctypes[] = {N_GSYM, N_STSYM, N_LCSYM, N_RSYM, N_SSYM, N_LSYM,
                    622:                        N_PSYM, 0};
                    623: varclass(class)
                    624: char class; {
                    625:        char *p;
                    626: 
                    627:        for (p=pctypes; *p; p++) {
                    628:                if (class == *p)
                    629:                        return(1);
                    630:        }
                    631:        return(0);
                    632: }

unix.superglobalmegacorp.com

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