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