|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.