Annotation of 43BSDTahoe/old/sdb/symt.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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