Annotation of researchv10no/cmd/sdb/symt.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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