Annotation of researchv10no/cmd/sdb/symt.c, revision 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.