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

Defined functions

adrtoext defined in line 856; used 1 times
adrtofilep defined in line 501; used 5 times
adrtolocal defined in line 889; used 1 times
adrtoparam defined in line 923; used 1 times
adrtoregvar defined in line 956; used 1 times
adrtostoffset defined in line 550; used 3 times
compar defined in line 618; used 2 times
curproc defined in line 226; used 12 times
docomm defined in line 810; used 2 times
extaddr defined in line 757; used 9 times
extlookup defined in line 778; used 1 times
findfile defined in line 255; used 4 times
findproc defined in line 238; used 8 times
getaddr defined in line 724; used 4 times
globallookup defined in line 409; used 2 times
initfp defined in line 53; used 1 times
lntoaddr defined in line 660; used 2 times
nametofile defined in line 645; used 1 times
nametooffset defined in line 629; used 1 times
setcur defined in line 564; used 8 times
setmap defined in line 982; used 1 times
slookinit defined in line 292; used 2 times
slooknext defined in line 296; used 2 times
slookup defined in line 283; used 1 times
stread defined in line 21; used 2 times
stseek defined in line 39; used 2 times
varclass defined in line 840; used 3 times

Defined variables

clevel defined in line 290; used 11 times
comfound defined in line 290; used 4 times
fnameflag defined in line 290; used 3 times
incomm defined in line 290; used 4 times
lastoffset defined in line 517; used 3 times
level defined in line 290; used 5 times
nullname defined in line 18; used 3 times
pctypes defined in line 838; used 1 times
sccsid defined in line 1; never used
symfil defined in line 13; used 5 times
symtab defined in line 17; used 6 times
u defined in line 11; used 1 times

Defined macros

STABTYPES defined in line 7; used 3 times
blseek defined in line 49; used 15 times
bread defined in line 48; used 22 times
Last modified: 1982-10-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3132
Valid CSS Valid XHTML 1.0 Strict