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

1.1       root        1: static char sccsid[] = "@(#)symt.c 4.1 10/9/80";
                      2: #include "head.h"
                      3: #include <a.out.h>
                      4: #include <stab.h>
                      5: 
                      6: #ifndef STABTYPES
                      7: #define        STABTYPES N_STAB
                      8: #endif
                      9: #include <sys/stat.h>
                     10: 
                     11: struct user u;
                     12: int compar();
                     13: char *symfil;
                     14: 
                     15: #ifdef FLEXNAMES
                     16: 
                     17: struct nlist *symtab;
                     18: char   nullname[] = {0,0,0,0,0,0,0,0,0};       /* a few 0 bytes */
                     19: off_t  stoff;
                     20: 
                     21: stread(buff, nbytes)
                     22: struct nlist *buff;
                     23: int nbytes;
                     24: {
                     25:        register int from = stoff;
                     26: 
                     27:        stoff += nbytes;
                     28:        if (stoff >= gstart)
                     29:                return (-1);
                     30:        if (nbytes < 0) {
                     31:                from = stoff;
                     32:                buff--;
                     33:        }
                     34:        from = (from - ststart);
                     35:        *buff = symtab[from/sizeof (struct nlist)];
                     36:        return (sizeof (struct nlist));
                     37: }
                     38: 
                     39: stseek(off, rel)
                     40: long off;
                     41: {
                     42: 
                     43:        if (rel == 1)
                     44:                stoff += off;
                     45:        else
                     46:                stoff = off;
                     47: }
                     48: #define        bread(a,b,c)    stread(b,c)
                     49: #define        blseek(a,b,c)   stseek(b,c)
                     50: #endif
                     51: 
                     52: /* initialize file and procedure tables */
                     53: initfp() {
                     54:        struct nlist stentry;
                     55:        register struct proct *procp;
                     56:        register struct filet *filep;
                     57:        struct stat stbuf;
                     58: 
                     59:        long soffset;
                     60:        int i, gflag = 0;
                     61:        char class;
                     62:        register char *p, *q;
                     63:        
                     64: #ifdef FLEXNAMES
                     65:        register struct nlist *sp;
                     66:        int malformed = 0;
                     67:        lseek(txtmap.ufd, gstart, 0);
                     68:        if (read(txtmap.ufd, &ssiz, sizeof(ssiz)) != sizeof (ssiz)) {
                     69:                printf("%s: no string table (old format?)\n", symfil);
                     70:                exit(1);
                     71:        }
                     72:        strtab = (char *)malloc(ssiz);
                     73:        if (strtab == 0) {
                     74:                printf("no room for %d bytes of string table\n", ssiz);
                     75:                exit(1);
                     76:        }
                     77:        ssiz -= sizeof (ssiz);
                     78:        if (read(txtmap.ufd, strtab+sizeof (ssiz), ssiz) != ssiz) {
                     79:                printf("%s: error reading string table\n", symfil);
                     80:                exit(1);
                     81:        }
                     82:        i = gstart - ststart;
                     83:        symtab = (struct nlist *)malloc(i);
                     84:        if (symtab == 0) {
                     85:                printf("no room for %d bytes of symbol table\n", i);
                     86:                exit(1);
                     87:        }
                     88:        lseek(txtmap.ufd, ststart, 0);
                     89:        if (read(txtmap.ufd, symtab, i) != i) {
                     90:                printf("%s: error reading symbol table\n", symfil);
                     91:                exit(1);
                     92:        }
                     93:        for (sp = &symtab[i/sizeof (struct nlist)]; --sp >= symtab; )
                     94:        if (sp->n_un.n_strx != 0) {
                     95:                if (sp->n_un.n_strx < sizeof (ssiz) || sp->n_un.n_strx >= ssiz) {
                     96:                        if (malformed == 0) {
                     97:                                printf("danger: mangled symbol table\n");
                     98:                                malformed = 1;
                     99:                        }
                    100:                        sp->n_un.n_name = nullname;
                    101:                } else
                    102:                        sp->n_un.n_name = strtab + sp->n_un.n_strx;
                    103:        } else
                    104:                sp->n_un.n_name = nullname;
                    105: #endif
                    106: #ifndef VMUNIX
                    107:        sbuf.fd = txtmap.ufd;
                    108: #endif
                    109:        firstdata = MAXPOS;
                    110:        soffset = ststart;
                    111:        blseek(&sbuf,ststart,0);
                    112:        filep = files = badfile = (struct filet *) sbrk(sizeof filep[0]);
                    113:        procp = procs = badproc = (struct proct *) sbrk(sizeof procp[0]);
                    114:        
                    115:        for(;;) {
                    116:                if (bread(&sbuf, &stentry, sizeof stentry) <
                    117:                                sizeof stentry) break;
                    118:                class = stentry.n_type & STABMASK;
                    119:                switch (class & STABMASK) {
                    120:                case N_SO:
                    121:                case N_SOL:
                    122:                        gflag++;
                    123:                        if (filep == badfile) {
                    124:                                p = sbrk(FILEINCR*sizeof filep[0]);
                    125:                                if (p < 0) {
                    126:                                        perror("sdb");
                    127:                                        exit(4);
                    128:                                }
                    129:                                q = p + FILEINCR*sizeof filep[0];
                    130:                                while (p > (char *) procs)
                    131:                                        *--q = *--p;
                    132:                                badfile += FILEINCR;
                    133:                                procp = (struct proct *)
                    134:                                    ((char *) procp +
                    135:                                                FILEINCR*sizeof filep[0]);
                    136:                                procs = (struct proct *)
                    137:                                    ((char *) procs +
                    138:                                                FILEINCR*sizeof filep[0]);
                    139:                                badproc = (struct proct *)
                    140:                                    ((char *)badproc +
                    141:                                                FILEINCR*sizeof filep[0]);
                    142:                        }
                    143:                        filep->faddr = stentry.n_value;
                    144:                        filep->lineflag = (class == N_SOL);
                    145:                        filep->stf_offset = soffset;
                    146: #ifndef FLEXNAMES
                    147:                        p = filep->sfilename;
                    148:                        for (;;) {
                    149:                                for (i=0; i<8; i++) *p++ = stentry.n_un.n_name[i];
                    150:                                if (*(p-1) == '\0') break;
                    151:                                if (bread(&sbuf, &stentry, sizeof stentry) 
                    152:                                                < sizeof stentry)
                    153:                                        error("Bad N_SO entry (1)");
                    154:                                if ((stentry.n_type & STABMASK) !=
                    155:                                                (unsigned char) class)
                    156:                                        error("Bad N_SO entry (2)");
                    157:                                soffset += sizeof stentry;
                    158:                        }
                    159: #else
                    160:                        filep->sfilename = stentry.n_un.n_name;
                    161: #endif
                    162:                        q = filep->sfilename;
                    163:                        for (p=fp; *q; *p++ = *q++) ;
                    164:                        *p = 0;
                    165:                        if (stat(filework, &stbuf) == -1)
                    166:                                printf("Warning: `%s' not found\n",
                    167:                                        filep->sfilename);
                    168:                        else if (stbuf.st_mtime > symtime)
                    169:                                printf("Warning: `%s' newer than `%s'\n",
                    170:                                        filep->sfilename,
                    171:                                        symfil);
                    172:                        filep++;
                    173:                        break;
                    174:                        
                    175:                case N_TEXT:
                    176:                        if (stentry.n_un.n_name[0] != '_') break;
                    177:                case N_FUN:
                    178:                case N_ENTRY:
                    179:                        if (procp == badproc) {
                    180:                                if (sbrk(PROCINCR*sizeof procp[0]) < 0) {
                    181:                                        perror("sdb");
                    182:                                        exit(4);
                    183:                                }
                    184:                                badproc += PROCINCR;
                    185:                        }
                    186: #ifndef FLEXNAMES
                    187:                        for(i=0; i<8; i++)
                    188:                                procp->pname[i] = stentry.n_un.n_name[i];
                    189: #else
                    190:                        procp->pname = stentry.n_un.n_name;
                    191: #endif
                    192:                        procp->paddr = stentry.n_value;
                    193:                        procp->st_offset = soffset;
                    194:                        procp->sfptr = (class != N_TEXT) ? filep - 1 : badfile;
                    195:                        procp->lineno = (class != N_TEXT) ? stentry.n_desc : 0;
                    196:                        procp->entrypt = (class & STABMASK) == N_ENTRY;
                    197:                        procp++;
                    198:                        break;
                    199:                }
                    200:                if (stentry.n_type & N_EXT) {
                    201:                        if (!extstart)
                    202:                                extstart = soffset;
                    203:                        if (stentry.n_type == N_DATA | N_EXT ||
                    204:                                        stentry.n_type == N_BSS | N_EXT ||
                    205:                                        stentry.n_value < firstdata)
                    206:                                firstdata = stentry.n_value;
                    207:                }
                    208:                soffset += sizeof stentry;
                    209:        }
                    210:        qsort(procs, procp-procs, sizeof procs[0], compar);
                    211:        badproc->st_offset = badfile->stf_offset = soffset;
                    212:        badproc->sfptr = procp->sfptr = badfile;
                    213: #ifndef FLEXNAMES
                    214:        badproc->pname[0] = badfile->sfilename[0]=
                    215:                procp->pname[0] = filep->sfilename[0] = '\0';
                    216: #else
                    217:        badproc->pname = badfile->sfilename=
                    218:                procp->pname = filep->sfilename = nullname;
                    219: #endif
                    220: 
                    221:        if (!gflag)
                    222:                printf("Warning: `%s' not compiled with -g\n", symfil);
                    223:        setcur(1);
                    224: }
                    225: 
                    226: /* returns current procedure from state (curfile, fline) */
                    227: struct proct *
                    228: curproc() {
                    229:        register ADDR addr;
                    230: 
                    231:        addr = getaddr("", fline);
                    232:        if (addr == -1) return(badproc);
                    233:        return(adrtoprocp(addr));
                    234: 
                    235: }
                    236: 
                    237: /* returns procedure s, uses curproc() if s == NULL */
                    238: 
                    239: struct proct *
                    240: findproc(s)
                    241: char *s; {
                    242:        register struct proct *p, *altproc;
                    243:        
                    244:        if (s[0] == '\0') return(curproc());
                    245:        altproc = badproc;
                    246:        
                    247:        for (p=procs; p->pname[0]; p++) {
                    248:                if (eqpat(s, p->pname)) return(p);
                    249:                if (p->pname[0] == '_' && eqpatr(s, p->pname+1, 1))
                    250:                        altproc = p;
                    251:        }
                    252:        return(altproc);
                    253: }
                    254: 
                    255: /* returns file s containing filename */
                    256: struct filet *
                    257: findfile(s)
                    258: char *s; {
                    259:        register struct filet *f;
                    260:        for (f=files; f->sfilename[0]; f++) {
                    261:                if (eqpat(f->sfilename, s)) { 
                    262:                        for( ; f->lineflag; f--) ;
                    263:                        if (f < files) error("Bad file array");
                    264:                        return(f);
                    265:                }
                    266:        }
                    267:        return(f);
                    268: }
                    269: 
                    270: /*
                    271:  * slookup():
                    272:  * looks up variable matching pat starting at (offset + sizeof stentry)
                    273:  * in a.out, searching backwards,
                    274:  * ignoring nested blocks to beginning to procedure.
                    275:  * Returns its offset and symbol table entries decoded in sl_*
                    276:  *
                    277:  * If comblk == "*" then match both within and outside common blocks,
                    278:  * if comblk == ""  then match only outside common blocks,
                    279:  *                  else match only within comblk.
                    280:  */
                    281:  
                    282: long
                    283: slookup(pat, poffset, stelt)
                    284: long poffset; char *pat; {
                    285:        slookinit();
                    286:        slooknext(pat, poffset, stelt, "*");
                    287: }
                    288: 
                    289: int clevel, level, fnameflag, comfound, incomm;
                    290: 
                    291: slookinit() {
                    292:        clevel = level = fnameflag = comfound = incomm = 0;
                    293: }
                    294: 
                    295: long
                    296: slooknext(pat, poffset, stelt, comblk)
                    297: long poffset; char *pat, *comblk; {
                    298:        register int i;
                    299:        register long offset;
                    300:        char class, *q;
                    301:        struct nlist stentry;
                    302:        struct proct *procp, *p;
                    303:        
                    304:        offset = poffset + sizeof stentry;
                    305:        if (debug) printf("slookup(%s,%d)\n",pat,offset);
                    306:        blseek(&sbuf, offset, 0);
                    307:        
                    308:        for (;;) {
                    309:                offset -= sizeof stentry;
                    310:                if (offset < ststart) break;
                    311:                if (bread(&sbuf, &stentry+1, -sizeof stentry) 
                    312:                        < sizeof stentry) break;
                    313:                class = stentry.n_type & STABMASK;
                    314:                switch (class & STABMASK) {
                    315:                case 0:
                    316:                        break;
                    317:                case N_FUN:
                    318:                        return(-1);
                    319:                case N_RBRAC:
                    320:                        level++;
                    321:                        break;
                    322:                case N_LBRAC:
                    323:                        level--;
                    324:                        break;
                    325:                case N_ECOMM:
                    326: #ifndef FLEXNAMES
                    327:                        for (q = &stentry.n_un.n_name[7]; q>=stentry.n_un.n_name; q--) {
                    328:                                if (*q == '_') {
                    329:                                        *q = '\0';
                    330:                                        break;
                    331:                                }
                    332:                        }
                    333: #else
                    334:                        for (q = stentry.n_un.n_name; *q; q++)
                    335:                                continue;
                    336:                        if (*--q == '_')
                    337:                                *q = 0;
                    338: #endif
                    339:                        if (eqpat(comblk, stentry.n_un.n_name))
                    340:                                comfound = 1;
                    341:                        incomm = 1;
                    342:                case N_ECOML:
                    343:                        clevel++;
                    344:                        break;
                    345:                case N_BCOMM:
                    346:                        comfound = incomm = 0;
                    347:                        clevel--;
                    348:                        break;
                    349:                case N_FNAME:
                    350:                        if (fnameflag)
                    351:                                break;
                    352:                        procp = findproc(stentry.n_un.n_name);
                    353:                        for (p=procs; p->pname[0]; p++) {
                    354:                                if (p->entrypt == 0 &&
                    355:                                        p->st_offset > procp->st_offset &&
                    356:                                        p->st_offset < offset)
                    357:                                                offset = p->st_offset;
                    358:                        }
                    359:                        clevel = level = 0;
                    360:                        fnameflag++;
                    361:                        blseek(&sbuf, offset, 0);
                    362:                        break;
                    363:                default:
                    364:                        if (level <= 0  &&  eqpat(pat, stentry.n_un.n_name) &&
                    365:                                stentry.n_un.n_name[0] && class & STABTYPES &&
                    366:                                (eqstr("*", comblk) ||
                    367:                                 (comblk[0] == '\0' && incomm == 0) ||
                    368:                                 comfound) &&
                    369:                                (stelt == (class == N_SSYM))) {
                    370:                                if (class == N_LENG) {
                    371:                                        sl_size = stentry.n_value;
                    372:                                        offset -= sizeof stentry;
                    373:                                        bread(&sbuf, &stentry+1,
                    374:                                                        -sizeof stentry);
                    375:                                        if (stentry.n_type&~N_EXT == N_BSS) {
                    376:                                                bread(&sbuf, &stentry+1,
                    377:                                                    -sizeof stentry);
                    378:                                                offset -= sizeof stentry;
                    379:                                        }
                    380:                                }
                    381:                                else sl_size = 0;
                    382:                                sl_class = stentry.n_type & STABMASK;
                    383:                                sl_type = stentry.n_desc;
                    384:                                sl_addr = stentry.n_value;
                    385: #ifndef FLEXNAMES
                    386:                                for (i=0; i<8; i++) sl_name[i] =
                    387:                                                stentry.n_un.n_name[i];
                    388: #else
                    389:                                sl_name = stentry.n_un.n_name;
                    390: #endif
                    391:                                if (clevel != 0) docomm(offset);
                    392:                                return(offset - sizeof stentry);
                    393:                        }
                    394:                }
                    395:        }
                    396:        return(-1);
                    397: }
                    398: 
                    399: /* 
                    400:  * Look up global variable matching pat starting at (filestart+sizeof stentry)
                    401:  * Return its offset and symbol table entries decoded in sl_*
                    402:  */
                    403: long
                    404: globallookup(pat, filestart, stelt)
                    405: char *pat; long filestart; {
                    406:        register int offset, i;
                    407:        struct nlist stentry;
                    408:        int class, clevel;
                    409:        
                    410:        if (debug) printf("globallookup(%s,%d)\n", pat,filestart);
                    411:        blseek(&sbuf, filestart, 0);
                    412:        offset = filestart - sizeof stentry;
                    413:        clevel = 0;
                    414:        do {
                    415:                if (bread(&sbuf, &stentry, sizeof stentry) <
                    416:                                sizeof stentry) return(-1);
                    417:                offset += sizeof stentry;
                    418:        } while ((stentry.n_type & STABMASK) == N_SO);
                    419:        for (;;) {
                    420:                class = stentry.n_type & STABMASK;
                    421:                switch (class & STABMASK) {
                    422:                case N_SO:
                    423:                        return(-1);
                    424:                case N_ECOMM:
                    425:                        clevel--;
                    426:                        break;
                    427:                case N_BCOMM:
                    428:                        clevel++;
                    429:                        break;
                    430:                default:
                    431:                if (eqpat(pat, stentry.n_un.n_name) 
                    432:                                && stentry.n_un.n_name[0] && class & STABTYPES) {
                    433:                        sl_class = stentry.n_type & STABMASK;
                    434:                        if (sl_class != N_GSYM && sl_class != N_SSYM && 
                    435:                                sl_class != N_STSYM && sl_class != N_LCSYM) goto g1;
                    436:                        if (stelt != (sl_class == N_SSYM)) goto g1;
                    437:                        sl_size = 0;
                    438:                        sl_type = stentry.n_desc;
                    439:                        sl_addr = stentry.n_value;
                    440: #ifndef FLEXNAMES
                    441:                        for (i=0; i<8; i++) sl_name[i] = stentry.n_un.n_name[i];
                    442: #else
                    443:                        sl_name = stentry.n_un.n_name;
                    444: #endif
                    445:                        if (clevel != 0) docomm(offset);
                    446:                        goto g2;
                    447:                }
                    448:                }
                    449: g1:            if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry)
                    450:                        return(-1);
                    451:                offset += sizeof stentry;
                    452:        }
                    453: g2:    bread(&sbuf, &stentry, sizeof stentry);
                    454:        if (stentry.n_type&~N_EXT==N_BSS) {
                    455:                bread(&sbuf, &stentry, sizeof stentry);
                    456:                offset += sizeof stentry;
                    457:        }
                    458:        if (((stentry.n_type & STABMASK) == N_LENG) &&
                    459:                        (eqpat(sl_name, stentry.n_un.n_name)))
                    460:                sl_size = stentry.n_value;
                    461: 
                    462:        if (sl_class == N_GSYM && (clevel == 0)) {
                    463:                blseek(&sbuf, extstart, 0);
                    464:                for(;;) {
                    465:                        if (bread(&sbuf, &stentry, sizeof stentry) 
                    466:                                        < sizeof stentry)
                    467:                                return(-1);
                    468:                        if (stentry.n_un.n_name[0] != '_') continue;
                    469:                        if (eqpatr(sl_name, stentry.n_un.n_name+1, 1)) {
                    470:                                sl_addr = stentry.n_value;
                    471:                                break;
                    472:                        }
                    473:                }
                    474:        }
                    475:        return(offset + sizeof stentry);
                    476: }
                    477: 
                    478: /* core address to procedure (pointer to proc array) */
                    479: struct proct *
                    480: adrtoprocp(addr) 
                    481: ADDR addr; {
                    482:        register struct proct *procp, *lastproc;
                    483:        lastproc = badproc;
                    484:        for (procp=procs; procp->pname[0]; procp++) {
                    485:                if (procp->paddr > addr) break;
                    486:                if (procp->entrypt == 0)
                    487:                        lastproc = procp;
                    488:        }
                    489:        return (lastproc);
                    490: }
                    491:  
                    492: 
                    493: /* core address to file (pointer to file array) */
                    494: struct filet *
                    495: adrtofilep(addr) 
                    496: ADDR addr; {
                    497:        register struct filet *filep;
                    498:        for (filep=files; filep->sfilename[0]; filep++) {
                    499:                if (filep->faddr > addr) break;
                    500:        }
                    501:        return (filep != files ? filep-1 : badfile);
                    502: }
                    503:  
                    504: /*
                    505:  * core address to linenumber 
                    506:  *  Sets external exactaddr to addr if addr is NOT the first instruction 
                    507:  * of a line, set to -1 otherwise.
                    508:  *  Sets external lnfaddr to address of first statement in line.
                    509:  */
                    510: long lastoffset;
                    511: 
                    512: adrtolineno(addr) 
                    513: ADDR addr; {
                    514:        register int lineno;
                    515:        long offset; 
                    516:        struct nlist stentry;
                    517:        
                    518:        exactaddr = addr;
                    519:        lineno = lastoffset = -1;
                    520:        offset = adrtoprocp(addr)->st_offset;
                    521:        blseek(&sbuf, offset, 0);
                    522:        for (;;) {
                    523:                if (bread(&sbuf, &stentry, sizeof stentry) 
                    524:                                < sizeof stentry) break;
                    525:                if (stentry.n_type == N_SO)
                    526:                        break;
                    527:                if (stentry.n_type == N_SLINE) {
                    528:                        if (stentry.n_value > addr)
                    529:                                break;
                    530:                        lastoffset = offset;
                    531:                        lineno = stentry.n_desc;
                    532:                        lnfaddr = stentry.n_value;
                    533:                        if (stentry.n_value == addr) 
                    534:                                exactaddr = -1;
                    535:                }
                    536:                offset += sizeof stentry;
                    537:        }
                    538:        return (lineno);
                    539: }
                    540: 
                    541: 
                    542: /* address to a.out offset */
                    543: long
                    544: adrtostoffset(addr) 
                    545: ADDR addr; {
                    546:        adrtolineno(addr);
                    547:        return(lastoffset);
                    548: }
                    549: 
                    550: 
                    551: /*
                    552:  * Set (curfile, lineno) from core image.
                    553:  * Returns 1 if there is a core image, 0 otherwise.
                    554:  *
                    555:  * Print the current line iff verbose is set.
                    556:  */
                    557: setcur(verbose) {
                    558:        register struct proct *procp;
                    559:        
                    560:        dot = *(ADDR *) (((ADDR) &u) + PC);
                    561:        
                    562:        if (dot == 0) {
                    563:                printf("No core image\n");
                    564:                goto setmain;
                    565:        }
                    566:        procp = adrtoprocp(dot);
                    567:        if ((procp->sfptr) != badfile) {
                    568:                finit(adrtofilep(procp->paddr)->sfilename);
                    569:                ffind(adrtolineno(dot));
                    570:                if (verbose) {
                    571:                        if (exactaddr != -1)
                    572:                                printf("0x%x in ", exactaddr);
                    573: #ifndef FLEXNAMES
                    574:                        printf("%.8s:", procp->pname);
                    575: #else
                    576:                        printf("%s:", procp->pname);
                    577: #endif
                    578:                        fprint();
                    579:                }
                    580:                return(1);
                    581:        }
                    582:        if (verbose) {
                    583:                if (procp->pname[0] == '_') 
                    584: #ifndef FLEXNAMES
                    585:                        printf("%.7s: address 0x%x\n", procp->pname+1, dot);
                    586: #else
                    587:                        printf("%s: address 0x%x\n", procp->pname+1, dot);
                    588: #endif
                    589:                else
                    590: #ifndef FLEXNAMES
                    591:                        printf("%.8s: address %d\n", procp->pname, dot);
                    592: #else
                    593:                        printf("%s: address %d\n", procp->pname, dot);
                    594: #endif
                    595:        }
                    596:        
                    597: setmain:
                    598:        procp = findproc("MAIN_");
                    599:        if ((procp->pname[0] != 'M') || (procp->sfptr == badfile)) {
                    600:                procp = findproc("main");
                    601:                if ((procp->pname[0] != 'm') || (procp->sfptr == badfile)) {
                    602:                        /* printf("main not compiled with debug flag\n"); */
                    603:                        return(0);
                    604:                }
                    605:        }
                    606:        finit(procp->sfptr->sfilename);
                    607:        ffind(procp->lineno);
                    608:        return(0);
                    609: }
                    610: 
                    611: compar(a, b)
                    612: struct proct *a, *b; {
                    613:        if (a->paddr == b->paddr) {
                    614:                if (a->pname[0] == '_') return(-1);
                    615:                if (b->pname[0] == '_') return(1);
                    616:                return(0);
                    617:        }
                    618:        return(a->paddr < b->paddr ? -1 : 1);
                    619: }
                    620: 
                    621: /* gets offset of file or procedure named s */
                    622: nametooffset(s)
                    623: char *s; {
                    624:        register struct filet *f;
                    625:        register struct proct *p;
                    626:        
                    627:        if (*s == '\0')
                    628:                return(-1);
                    629:        if (eqany('.', s)) {
                    630:                f = findfile(s);
                    631:                return(f->sfilename[0] ? f->stf_offset : -1);
                    632:        }
                    633:        p = findproc(s);
                    634:        return(p->pname[0] ? p->st_offset : -1);
                    635: }
                    636: 
                    637: /* returns s if its a filename, its file otherwise */
                    638: char *
                    639: nametofile(s)
                    640: char *s; {
                    641:        register struct proct *p;
                    642:        
                    643:        if (eqany('.', s)) {
                    644:                return(s);
                    645:        }
                    646:        p = findproc(s);
                    647:        return(adrtofilep(p->paddr)->sfilename);
                    648: }
                    649: 
                    650: 
                    651: /* line number to address, starting at offset in a.out */
                    652: /* assumes that offset is within file */
                    653: lntoaddr(lineno, offset, file) 
                    654: long offset; char *file; {
                    655:        struct nlist stentry;
                    656:        register int i, ignore = 0;
                    657:        register int bestln=BIGNUM;
                    658:        ADDR bestaddr;
                    659:        char *p;
                    660:        
                    661:        blseek(&sbuf, offset, 0);
                    662:        
                    663:        do {
                    664:                if (bread(&sbuf, &stentry, sizeof stentry) <
                    665:                                sizeof stentry) return(-1);
                    666:        } while ((stentry.n_type & STABMASK) == N_SO);
                    667:        for (;;) {
                    668:                switch(stentry.n_type & STABMASK) {
                    669:                case N_SLINE:
                    670:                        if (!ignore) {
                    671:                                if (stentry.n_desc == lineno)
                    672:                                        return(stentry.n_value);
                    673:                                if (stentry.n_desc > lineno &&
                    674:                                        stentry.n_desc < bestln) {
                    675:                                        bestln = stentry.n_desc;
                    676:                                        bestaddr = stentry.n_value;
                    677:                                }
                    678:                        }
                    679:                        break;
                    680: 
                    681:                case N_SO:
                    682:                        goto ret;
                    683: 
                    684:                case N_SOL:
                    685:                        p = file;
                    686: #ifndef FLEXNAMES
                    687:                        for (;;) {
                    688:                                for (i=0; i<8; i++) {
                    689:                                        if (*p != stentry.n_un.n_name[i]) goto neq;
                    690:                                        if (*p++ == '\0') break;
                    691:                                }
                    692:                                if (stentry.n_un.n_name[7] == '\0')
                    693:                                        break;
                    694:                                if (bread(&sbuf, &stentry, sizeof stentry) 
                    695:                                                < sizeof stentry)
                    696:                                        error("Bad N_SO entry (1)");
                    697:                                if ((stentry.n_type & STABMASK) != 
                    698:                                                (unsigned char) N_SOL)
                    699:                                        error("Bad N_SO entry (2)");
                    700:                        }
                    701: #else
                    702:                        if (strcmp(file, stentry.n_un.n_name))
                    703:                                goto neq;
                    704: #endif
                    705:                        ignore = 0;
                    706:                        break;
                    707: 
                    708: neq:                   ignore++;
                    709:                        break;
                    710:                }
                    711:                if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry) 
                    712:                        break;
                    713:        }
                    714: ret:   return(bestln == BIGNUM ? -1 : bestaddr);
                    715: }
                    716: 
                    717: /* gets address of proc:number */
                    718: getaddr(proc,integ) 
                    719: char *proc; {
                    720:        register long offset;
                    721:        register char *s, *f;
                    722:        ADDR addr;
                    723:        
                    724:        s = proc[0] ? proc : curfile;
                    725:        if (*s == '\0')
                    726:                return(-1);
                    727:        offset = nametooffset(s);
                    728:        f = nametofile(s);
                    729:        if (debug) printf("getaddr() computed offset %d", offset);
                    730:        if (offset == -1) {
                    731:                addr = extaddr(proc);
                    732:                if (addr != -1) addr += 2;  /* MACHINE DEPENDENT */
                    733:                if (debug) printf(" extaddr computed %d\n", addr);
                    734:                return(addr);
                    735:        }
                    736:        if (integ)
                    737:                addr = lntoaddr(integ, offset, s);
                    738:        else {
                    739:                ADDR oldaddr;
                    740:                oldaddr = findproc(proc)->paddr + 2;  /* MACHINE DEPENDENT */
                    741:                addr = lntoaddr(adrtolineno(addr)+1, offset, f);
                    742:                if (addr == -1)
                    743:                        addr = oldaddr;
                    744:        }
                    745:        if (debug) printf(" and addr %d\n", addr);
                    746:        if (addr == -1) return(-1);
                    747:        return(addr);
                    748: }
                    749: 
                    750: /* returns address of external */
                    751: ADDR
                    752: extaddr(name)
                    753: char *name; {
                    754:        struct nlist stentry;
                    755:        blseek(&sbuf, extstart, 0);
                    756:        
                    757:        for (;;) {
                    758:                if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry)
                    759:                        return(-1);
                    760:                if (stentry.n_un.n_name[0] == '_' && 
                    761:                            eqpatr(name, stentry.n_un.n_name+1, 1)) 
                    762:                        return(stentry.n_value);
                    763:        }
                    764: }
                    765: 
                    766: 
                    767: /* 
                    768:  * Look up external data symbol matching pat starting at 
                    769:  *  (filestart+sizeof stentry)
                    770:  * Return its address in sl_addr and name in sl_name.
                    771:  */
                    772: long
                    773: extlookup(pat, filestart)
                    774: char *pat; long filestart; {
                    775:        register int offset, i;
                    776:        struct nlist stentry;
                    777:        
                    778:        blseek(&sbuf, filestart, 0);
                    779:        offset = filestart - sizeof stentry;
                    780:        do {
                    781:                if (bread(&sbuf, &stentry, sizeof stentry) <
                    782:                                sizeof stentry) return(-1);
                    783:                offset += sizeof stentry;
                    784:        } while ((stentry.n_type & STABMASK) == N_SO);
                    785:        for (;;) {
                    786:                if (stentry.n_un.n_name[0] == '_' && 
                    787:                            stentry.n_type == (N_DATA | N_EXT) &&
                    788:                            eqpatr(pat, stentry.n_un.n_name+1, 1)) {
                    789:                        sl_addr = stentry.n_value;
                    790: #ifndef FLEXNAMES
                    791:                        for (i=0; i<7; i++) sl_name[i] = stentry.n_un.n_name[i+1];
                    792: #else
                    793:                        sl_name = stentry.n_un.n_name;
                    794: #endif
                    795:                        return(offset + sizeof stentry);
                    796:                }
                    797: g1:            if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry)
                    798:                        return(-1);
                    799:                offset += sizeof stentry;
                    800:        }
                    801: }
                    802: 
                    803: /* find enclosing common blocks and fix up addresses */
                    804: docomm(offset)
                    805: long offset; {
                    806:        struct nlist stentry;
                    807: 
                    808:        for (;;) {
                    809:                if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry) {
                    810:                        error("Bad common block");
                    811:                        return;
                    812:                }
                    813:                sl_class = N_GSYM;
                    814:                if ((stentry.n_type & STABMASK) == N_ECOMM) {
                    815:                        sl_addr += extaddr(stentry.n_un.n_name);
                    816:                        blseek(&sbuf, offset, 0);
                    817:                        return;
                    818:                }
                    819:                if ((stentry.n_type & STABMASK) == N_ECOML) {
                    820:                        sl_addr += stentry.n_value;
                    821:                        blseek(&sbuf, offset, 0);
                    822:                        return;
                    823:                }
                    824:        }
                    825: }
                    826: 
                    827: /* determine if class is that of a variable */
                    828: char pctypes[] = {N_GSYM, N_STSYM, N_LCSYM, N_RSYM, N_SSYM, N_LSYM,
                    829:                        N_PSYM, 0};
                    830: varclass(class)
                    831: char class; {
                    832:        char *p;
                    833: 
                    834:        for (p=pctypes; *p; p++) {
                    835:                if (class == *p)
                    836:                        return(1);
                    837:        }
                    838:        return(0);
                    839: }
                    840: 
                    841: /*
                    842:  * address to external name 
                    843:  * returns difference between addr and address of external
                    844:  * name returned in sl_name
                    845:  */
                    846: adrtoext(addr) 
                    847: ADDR addr; {
                    848:        struct nlist stentry;
                    849:        register int i, prevdiff = MAXPOS, diff;
                    850: 
                    851:        blseek(&sbuf, extstart, 0);
                    852:        for (;;) {
                    853:                if (bread(&sbuf, &stentry, sizeof stentry) 
                    854:                                < sizeof stentry)
                    855:                        return (prevdiff!=MAXPOS ? prevdiff : -1);
                    856:                if (stentry.n_type == (N_DATA | N_EXT) ||
                    857:                    stentry.n_type == (N_BSS | N_EXT)) {
                    858:                        diff = addr - stentry.n_value;
                    859:                        if (diff >= 0 && diff < prevdiff) {
                    860: #ifndef FLEXNAMES
                    861:                                for (i=0; i<7; i++)
                    862:                                        sl_name[i] = stentry.n_un.n_name[i+1];
                    863: #else
                    864:                                sl_name = stentry.n_un.n_name;
                    865: #endif
                    866:                                if (diff == 0)
                    867:                                        return(0);
                    868:                                prevdiff = diff;
                    869:                        }
                    870:                }
                    871:        }
                    872: }
                    873: 
                    874: /*
                    875:  * address to local name in procp
                    876:  * returns difference between addr and address of local
                    877:  * returned in sl_name
                    878:  */
                    879: adrtolocal(addr, procp) 
                    880: ADDR addr; struct proct *procp; {
                    881:        struct nlist stentry;
                    882:        register int i, prevdiff = MAXPOS, diff;
                    883: 
                    884:        blseek(&sbuf, procp->st_offset + sizeof stentry, 0);
                    885:        for (;;) {
                    886:                if (bread(&sbuf, &stentry, sizeof stentry) 
                    887:                                < sizeof stentry)
                    888:                        return(prevdiff!=MAXPOS ? prevdiff : -1);
                    889:                if (stentry.n_type == N_FUN)
                    890:                        return(prevdiff!=MAXPOS ? prevdiff : -1);
                    891:                if (stentry.n_type == N_LSYM) {
                    892:                        diff = addr - stentry.n_value;
                    893:                        if (diff >= 0 && diff < prevdiff) {
                    894: #ifndef FLEXNAMES
                    895:                                for (i=0; i<8; i++)
                    896:                                        sl_name[i] = stentry.n_un.n_name[i];
                    897: #else
                    898:                                sl_name = stentry.n_un.n_name;
                    899: #endif
                    900:                                if (diff == 0)
                    901:                                        return(0);
                    902:                                prevdiff = diff;
                    903:                        }
                    904:                }
                    905:        }
                    906: }
                    907: 
                    908: /*
                    909:  * address to parameter name in procp
                    910:  * returns difference between addr and address of local
                    911:  * returned in sl_name
                    912:  */
                    913: adrtoparam(addr, procp) 
                    914: ADDR addr; struct proct *procp; {
                    915:        struct nlist stentry;
                    916:        register int i, prevdiff = MAXPOS, diff;
                    917: 
                    918:        blseek(&sbuf, procp->st_offset + sizeof stentry, 0);
                    919:        for (;;) {
                    920:                if (bread(&sbuf, &stentry, sizeof stentry) 
                    921:                                < sizeof stentry) 
                    922:                        return(prevdiff!=MAXPOS ? prevdiff : -1);
                    923:                if (stentry.n_type == N_FUN)
                    924:                        return(prevdiff!=MAXPOS ? prevdiff : -1);
                    925:                if (stentry.n_type == N_PSYM) {
                    926:                        diff = addr - stentry.n_value;
                    927:                        if (diff >= 0 && diff < prevdiff) {
                    928: #ifndef FLEXNAMES
                    929:                                for (i=0; i<8; i++)
                    930:                                        sl_name[i] = stentry.n_un.n_name[i];
                    931: #else
                    932:                                sl_name = stentry.n_un.n_name;
                    933: #endif
                    934:                                if (diff == 0)
                    935:                                        return(0);
                    936:                                prevdiff = diff;
                    937:                        }
                    938:                }
                    939:        }
                    940: }
                    941: 
                    942: /*
                    943:  * register number to register variable name in procp
                    944:  * returned in sl_name
                    945:  */
                    946: adrtoregvar(regno, procp) 
                    947: ADDR regno; struct proct *procp; {
                    948:        struct nlist stentry;
                    949:        register int i;
                    950: 
                    951:        blseek(&sbuf, procp->st_offset + sizeof stentry, 0);
                    952:        for (;;) {
                    953:                if (bread(&sbuf, &stentry, sizeof stentry) 
                    954:                                < sizeof stentry) return(-1);
                    955:                if (stentry.n_type == N_FUN)
                    956:                        return(-1);
                    957:                if (stentry.n_type == N_RSYM) {
                    958:                        if (stentry.n_value == regno) {
                    959: #ifndef FLEXNAMES
                    960:                                for (i=0; i<8; i++)
                    961:                                        sl_name[i] = stentry.n_un.n_name[i];
                    962: #else
                    963:                                sl_name = stentry.n_un.n_name;
                    964: #endif
                    965:                                return(0);
                    966:                        }
                    967:                }
                    968:        }
                    969: }
                    970: 
                    971: /* sets file map for M command */
                    972: setmap(s)
                    973: char *s; {
                    974:        union {
                    975:                MAP *m;
                    976:                L_INT *mp;
                    977:        } amap;
                    978:        int starflag = 0;
                    979: 
                    980:        amap.mp = 0;
                    981:        for (; *s; s++) {
                    982:                switch (*s) {
                    983:                case '/':
                    984:                        amap.m = &datmap;
                    985:                        break;
                    986:                case '?':
                    987:                        amap.m = &txtmap;
                    988:                        break;
                    989:                case '*':
                    990:                        starflag++;
                    991:                        break;
                    992:                default:        
                    993:                        goto sout;
                    994:                }
                    995:        }
                    996:        
                    997: sout:  if (amap.mp == 0) {
                    998:                error("Map `?' or `/' must be specified");
                    999:                return;
                   1000:        }
                   1001:        if (starflag)
                   1002:                amap.mp += 3;
                   1003:        for (; *s; s++) {
                   1004:                if (*s >= '0' && *s <= '9')
                   1005:                        *(amap.mp)++ = readint(&s);
                   1006:        }
                   1007: }

unix.superglobalmegacorp.com

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