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