|
|
1.1 ! root 1: #include "head.h" ! 2: #include <a.out.h> ! 3: #include <sys/stat.h> ! 4: ! 5: struct user u; ! 6: int compar(); ! 7: char *symfil; ! 8: ! 9: /* initialize file and procedure tables */ ! 10: initfp() { ! 11: struct nlist stentry; ! 12: register struct proct *procp; ! 13: register struct filet *filep; ! 14: struct stat stbuf; ! 15: ! 16: long soffset; ! 17: int i; ! 18: char class; ! 19: register char *p, *q; ! 20: ! 21: sbuf.fd = txtmap.ufd; ! 22: soffset = ststart; ! 23: blseek(&sbuf,ststart,0); ! 24: filep = files = badfile = (struct filet *) sbrk(sizeof filep[0]); ! 25: procp = procs = badproc = (struct proct *) sbrk(sizeof procp[0]); ! 26: ! 27: for(;;) { ! 28: if (bread(&sbuf, &stentry, sizeof stentry) < ! 29: sizeof stentry) break; ! 30: class = stentry.n_type & STABMASK; ! 31: switch (class & STABMASK) { ! 32: case N_SO: ! 33: case N_SOL: ! 34: if (filep == badfile) { ! 35: p = sbrk(FILEINCR*sizeof filep[0]); ! 36: if (p < 0) { ! 37: perror("sdb"); ! 38: exit(4); ! 39: } ! 40: q = p + FILEINCR*sizeof filep[0]; ! 41: while (p > (char *) procs) ! 42: *--q = *--p; ! 43: badfile += FILEINCR; ! 44: procp = (struct proct *) ! 45: ((char *) procp + ! 46: FILEINCR*sizeof filep[0]); ! 47: procs = (struct proct *) ! 48: ((char *) procs + ! 49: FILEINCR*sizeof filep[0]); ! 50: badproc = (struct proct *) ! 51: ((char *)badproc + ! 52: FILEINCR*sizeof filep[0]); ! 53: } ! 54: filep->faddr = stentry.n_value; ! 55: filep->lineflag = (class == N_SOL); ! 56: filep->stf_offset = soffset; ! 57: p = filep->sfilename; ! 58: for (;;) { ! 59: for (i=0; i<8; i++) *p++ = stentry.n_name[i]; ! 60: if (*(p-1) == '\0') break; ! 61: if (bread(&sbuf, &stentry, sizeof stentry) ! 62: < sizeof stentry) ! 63: error("Bad N_SO entry (1)"); ! 64: if ((stentry.n_type & STABMASK) != ! 65: (unsigned char) class) ! 66: error("Bad N_SO entry (2)"); ! 67: soffset += sizeof stentry; ! 68: } ! 69: q = filep->sfilename; ! 70: for (p=fp; *q; *p++ = *q++) ; ! 71: *p = 0; ! 72: if (stat(filework, &stbuf) == -1) ! 73: printf("Warning: `%s' not found\n", ! 74: filep->sfilename); ! 75: else if (stbuf.st_mtime > symtime) ! 76: printf("Warning: `%s' newer than `%s'\n", ! 77: filep->sfilename, ! 78: symfil); ! 79: filep++; ! 80: break; ! 81: ! 82: case N_TEXT: ! 83: if (stentry.n_name[0] != '_') break; ! 84: case N_FUN: ! 85: case N_ENTRY: ! 86: if (procp == badproc) { ! 87: if (sbrk(PROCINCR*sizeof procp[0]) < 0) { ! 88: perror("sdb"); ! 89: exit(4); ! 90: } ! 91: badproc += PROCINCR; ! 92: } ! 93: for(i=0; i<8; i++) ! 94: procp->pname[i] = stentry.n_name[i]; ! 95: procp->paddr = stentry.n_value; ! 96: procp->st_offset = soffset; ! 97: procp->sfptr = (class != N_TEXT) ? filep - 1 : badfile; ! 98: procp->lineno = (class != N_TEXT) ? stentry.n_desc : 0; ! 99: procp->entrypt = (class & STABMASK) == N_ENTRY; ! 100: procp++; ! 101: break; ! 102: } ! 103: if (stentry.n_type & N_EXT && !extstart) { ! 104: extstart = soffset; ! 105: } ! 106: soffset += sizeof stentry; ! 107: } ! 108: qsort(procs, procp-procs, sizeof procs[0], compar); ! 109: badproc->st_offset = soffset; ! 110: badproc->sfptr = procp->sfptr = badfile; ! 111: badproc->pname[0] = badfile->sfilename[0]= ! 112: procp->pname[0] = filep->sfilename[0] = '\0'; ! 113: ! 114: setcur(1); ! 115: } ! 116: ! 117: /* returns current procedure from state (curfile, fline) */ ! 118: struct proct * ! 119: curproc() { ! 120: register ADDR addr; ! 121: ! 122: addr = getaddr("", fline); ! 123: if (addr == -1) return(badproc); ! 124: return(adrtoprocp(addr)); ! 125: ! 126: } ! 127: ! 128: /* returns procedure s, uses curproc() if s == NULL */ ! 129: ! 130: struct proct * ! 131: findproc(s) ! 132: char *s; { ! 133: register struct proct *p; ! 134: ! 135: if (s[0] == '\0') return(curproc()); ! 136: ! 137: for(p=procs; p->pname[0]; p++) ! 138: if (eqstr(p->pname, s)) return(p); ! 139: ! 140: if (debug) printf("%s(): unknown name\n", s); ! 141: return(badproc); ! 142: } ! 143: ! 144: /* returns file s containing filename */ ! 145: struct filet * ! 146: findfile(s) ! 147: char *s; { ! 148: register struct filet *f; ! 149: for (f=files; f->sfilename[0]; f++) { ! 150: if (eqstr(f->sfilename, s)) { ! 151: for( ; f->lineflag; f--) ; ! 152: if (f < files) error("Bad file array"); ! 153: return(f); ! 154: } ! 155: } ! 156: return(f); ! 157: } ! 158: ! 159: /* ! 160: * slookup(): ! 161: * looks up variable matching pat starting at offset in a.out, searching ! 162: * backwards, ignoring nested blocks to beginning to procedure. ! 163: * Returns its offset and symbol table entries decoded in sl_* ! 164: * ! 165: * If comblk == "*" then match both within and outside common blocks, ! 166: * if comblk == "" then match only outside common blocks, ! 167: * else match only within comblk. ! 168: */ ! 169: ! 170: long ! 171: slookup(pat, poffset, stelt) ! 172: long poffset; char *pat; { ! 173: slookinit(); ! 174: slooknext(pat, poffset, stelt, "*"); ! 175: } ! 176: ! 177: int clevel, level, fnameflag, comfound, incomm; ! 178: ! 179: slookinit() { ! 180: clevel = level = fnameflag = comfound = incomm = 0; ! 181: } ! 182: ! 183: long ! 184: slooknext(pat, poffset, stelt, comblk) ! 185: long poffset; char *pat, *comblk; { ! 186: register int i; ! 187: register long offset; ! 188: char class, *q; ! 189: struct nlist stentry; ! 190: struct proct *procp, *p; ! 191: ! 192: offset = poffset + sizeof stentry; ! 193: if (debug) printf("slookup(%s,%d)\n",pat,offset); ! 194: blseek(&sbuf, offset, 0); ! 195: ! 196: for (;;) { ! 197: offset -= sizeof stentry; ! 198: if (offset < ststart) break; ! 199: if (bread(&sbuf, &stentry+1, -sizeof stentry) ! 200: < sizeof stentry) break; ! 201: class = stentry.n_type & STABMASK; ! 202: switch (class & STABMASK) { ! 203: case 0: ! 204: break; ! 205: case N_FUN: ! 206: return(-1); ! 207: case N_RBRAC: ! 208: level++; ! 209: break; ! 210: case N_LBRAC: ! 211: level--; ! 212: break; ! 213: case N_ECOMM: ! 214: for (q = &stentry.n_name[7]; q>=stentry.n_name; q--) { ! 215: if (*q == '_') { ! 216: *q = '\0'; ! 217: break; ! 218: } ! 219: } ! 220: if (eqpat(comblk, stentry.n_name)) ! 221: comfound = 1; ! 222: incomm = 1; ! 223: case N_ECOML: ! 224: clevel++; ! 225: break; ! 226: case N_BCOMM: ! 227: comfound = incomm = 0; ! 228: clevel--; ! 229: break; ! 230: case N_FNAME: ! 231: if (fnameflag) ! 232: break; ! 233: procp = findproc(stentry.n_name); ! 234: for (p=procs; p->pname[0]; p++) { ! 235: if (p->entrypt == 0 && ! 236: p->st_offset > procp->st_offset && ! 237: p->st_offset < offset) ! 238: offset = p->st_offset; ! 239: } ! 240: clevel = level = 0; ! 241: fnameflag++; ! 242: blseek(&sbuf, offset, 0); ! 243: break; ! 244: default: ! 245: if (level <= 0 && eqpat(pat, stentry.n_name) && ! 246: stentry.n_name[0] && class & STABTYPES && ! 247: (eqstr("*", comblk) || ! 248: (comblk[0] == '\0' && incomm == 0) || ! 249: comfound) && ! 250: (stelt == (class == N_SSYM))) { ! 251: if (class == N_LENG) { ! 252: sl_size = stentry.n_value; ! 253: offset -= sizeof stentry; ! 254: bread(&sbuf, &stentry+1, ! 255: -sizeof stentry); ! 256: } ! 257: else sl_size = 0; ! 258: sl_class = stentry.n_type & STABMASK; ! 259: sl_type = stentry.n_desc; ! 260: sl_addr = stentry.n_value; ! 261: for (i=0; i<8; i++) sl_name[i] = ! 262: stentry.n_name[i]; ! 263: if (clevel != 0) docomm(offset); ! 264: return(offset - sizeof stentry); ! 265: } ! 266: } ! 267: } ! 268: return(-1); ! 269: } ! 270: ! 271: /* ! 272: * Look up global variable matching pat ! 273: * Return its offset and symbol table entries decoded in sl_* ! 274: */ ! 275: long ! 276: globallookup(pat, filestart, stelt) ! 277: char *pat; long filestart; { ! 278: register int offset, i; ! 279: struct nlist stentry; ! 280: int class, clevel; ! 281: ! 282: if (debug) printf("globallookup(%s,%d)\n", pat,filestart); ! 283: blseek(&sbuf, filestart, 0); ! 284: offset = filestart - sizeof stentry; ! 285: clevel = 0; ! 286: do { ! 287: if (bread(&sbuf, &stentry, sizeof stentry) < ! 288: sizeof stentry) return(-1); ! 289: offset += sizeof stentry; ! 290: } while ((stentry.n_type & STABMASK) == N_SO); ! 291: for (;;) { ! 292: class = stentry.n_type & STABMASK; ! 293: switch (class & STABMASK) { ! 294: case N_SO: ! 295: return(-1); ! 296: case N_ECOMM: ! 297: clevel--; ! 298: break; ! 299: case N_BCOMM: ! 300: clevel++; ! 301: break; ! 302: default: ! 303: if (eqpat(pat, stentry.n_name) ! 304: && stentry.n_name[0] && class & STABTYPES) { ! 305: sl_class = stentry.n_type & STABMASK; ! 306: if (sl_class != N_GSYM && sl_class != N_SSYM && ! 307: sl_class != N_STSYM) goto g1; ! 308: if (stelt != (sl_class == N_SSYM)) goto g1; ! 309: sl_size = 0; ! 310: sl_type = stentry.n_desc; ! 311: sl_addr = stentry.n_value; ! 312: for (i=0; i<8; i++) sl_name[i] = stentry.n_name[i]; ! 313: if (clevel != 0) docomm(offset); ! 314: goto g2; ! 315: } ! 316: } ! 317: g1: if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry) ! 318: return(-1); ! 319: offset += sizeof stentry; ! 320: } ! 321: g2: bread(&sbuf, &stentry, sizeof stentry); ! 322: if (((stentry.n_type & STABMASK) == N_LENG) && ! 323: (eqpat(sl_name, stentry.n_name))) ! 324: sl_size = stentry.n_value; ! 325: ! 326: if (sl_class == N_GSYM && (clevel == 0)) { ! 327: blseek(&sbuf, extstart, 0); ! 328: for(;;) { ! 329: if (bread(&sbuf, &stentry, sizeof stentry) ! 330: < sizeof stentry) ! 331: return(-1); ! 332: if (stentry.n_name[0] != '_') continue; ! 333: if (eqpatr(sl_name, stentry.n_name+1, 1)) { ! 334: sl_addr = stentry.n_value; ! 335: break; ! 336: } ! 337: } ! 338: } ! 339: return(offset + sizeof stentry); ! 340: } ! 341: ! 342: /* core address to procedure (pointer to proc array) */ ! 343: struct proct * ! 344: adrtoprocp(addr) ! 345: ADDR addr; { ! 346: register struct proct *procp, *lastproc; ! 347: lastproc = badproc; ! 348: for (procp=procs; procp->pname[0]; procp++) { ! 349: if (procp->paddr > addr) break; ! 350: if (procp->entrypt == 0) ! 351: lastproc = procp; ! 352: } ! 353: return (lastproc); ! 354: } ! 355: ! 356: ! 357: /* core address to file (pointer to file array) */ ! 358: struct filet * ! 359: adrtofilep(addr) ! 360: ADDR addr; { ! 361: register struct filet *filep; ! 362: for (filep=files; filep->sfilename[0]; filep++) { ! 363: if (filep->faddr > addr) break; ! 364: } ! 365: return (filep != files ? filep-1 : badfile); ! 366: } ! 367: ! 368: /* core address to linenumber */ ! 369: long lastoffset; ! 370: ! 371: adrtolineno(addr) ! 372: ADDR addr; { ! 373: register int lineno; ! 374: long offset; ! 375: struct nlist stentry; ! 376: ! 377: lineno = lastoffset = -1; ! 378: offset = adrtoproc(addr)->st_offset; ! 379: blseek(&sbuf, offset, 0); ! 380: for (;;) { ! 381: if (bread(&sbuf, &stentry, sizeof stentry) ! 382: < sizeof stentry) break; ! 383: if (stentry.n_type == N_SLINE) { ! 384: if (stentry.n_value > addr) break; ! 385: lastoffset = offset; ! 386: lineno = stentry.n_desc; ! 387: } ! 388: offset += sizeof stentry; ! 389: } ! 390: return (lineno); ! 391: } ! 392: ! 393: ! 394: /* address to a.out offset */ ! 395: long ! 396: adrtostoffset(addr) ! 397: ADDR addr; { ! 398: adrtolineno(addr); ! 399: return(lastoffset); ! 400: } ! 401: ! 402: ! 403: /* ! 404: * Set (curfile, lineno) from core image. ! 405: * Returns 1 if there is a core image, 0 otherwise. ! 406: * ! 407: * Print the current line iff verbose is set. ! 408: */ ! 409: setcur(verbose) { ! 410: register struct proct *procp; ! 411: ! 412: dot = *(ADDR *) (((ADDR) &u) + PC); ! 413: ! 414: if (dot == 0) { ! 415: printf("No core image\n"); ! 416: goto setmain; ! 417: } ! 418: procp = adrtoprocp(dot); ! 419: if ((procp->sfptr) != badfile) { ! 420: finit(adrtofilep(procp->paddr)->sfilename); ! 421: ffind(adrtolineno(dot)); ! 422: if (verbose) { ! 423: printf("%.8s:", procp->pname); ! 424: fprint(); ! 425: } ! 426: return(1); ! 427: } ! 428: if (verbose) { ! 429: if (procp->pname[0] == '_') ! 430: printf("%.7s: address 0x%x\n", procp->pname+1, dot); ! 431: else ! 432: printf("%.8s: address %d\n", procp->pname, dot); ! 433: } ! 434: ! 435: setmain: ! 436: procp = findproc("MAIN_"); ! 437: if ((procp->pname[0] != 'M') || (procp->sfptr == badfile)) { ! 438: procp = findproc("main"); ! 439: if ((procp->pname[0] != 'm') || (procp->sfptr == badfile)) { ! 440: nolines = 1; ! 441: printf("main not compiled with debug flag\n"); ! 442: return(0); ! 443: } ! 444: } ! 445: finit(procp->sfptr->sfilename); ! 446: ffind(procp->lineno); ! 447: return(0); ! 448: } ! 449: ! 450: compar(a, b) ! 451: struct proct *a, *b; { ! 452: if (a->paddr == b->paddr) { ! 453: if (a->pname[0] == '_') return(-1); ! 454: if (b->pname[0] == '_') return(1); ! 455: return(0); ! 456: } ! 457: return(a->paddr < b->paddr ? -1 : 1); ! 458: } ! 459: ! 460: /* gets offset of file or procedure named s */ ! 461: nametooffset(s) ! 462: char *s; { ! 463: register struct filet *f; ! 464: register struct proct *p; ! 465: ! 466: if (*s == '\0') ! 467: return(-1); ! 468: if (eqany('.', s)) { ! 469: f = findfile(s); ! 470: return(f->sfilename[0] ? f->stf_offset : -1); ! 471: } ! 472: p = findproc(s); ! 473: return(p->pname[0] ? p->st_offset : -1); ! 474: } ! 475: /* returns s if its a filename, its file otherwise */ ! 476: char * ! 477: nametofile(s) ! 478: char *s; { ! 479: register struct proct *p; ! 480: ! 481: if (eqany('.', s)) { ! 482: return(s); ! 483: } ! 484: p = findproc(s); ! 485: return(adrtofilep(p->paddr)->sfilename); ! 486: } ! 487: ! 488: ! 489: /* line number to address, starting at offset in a.out */ ! 490: /* assumes that offset is within file */ ! 491: lntoaddr(lineno, offset, file) ! 492: long offset; char *file; { ! 493: struct nlist stentry; ! 494: register int i, ignore = 0; ! 495: register int bestln=BIGNUM; ! 496: ADDR bestaddr; ! 497: char *p; ! 498: ! 499: blseek(&sbuf, offset, 0); ! 500: ! 501: do { ! 502: if (bread(&sbuf, &stentry, sizeof stentry) < ! 503: sizeof stentry) return(-1); ! 504: } while ((stentry.n_type & STABMASK) == N_SO); ! 505: for (;;) { ! 506: switch(stentry.n_type & STABMASK) { ! 507: case N_SLINE: ! 508: if (!ignore) { ! 509: if (stentry.n_desc == lineno) ! 510: return(stentry.n_value); ! 511: if (stentry.n_desc > lineno && ! 512: stentry.n_desc < bestln) { ! 513: bestln = stentry.n_desc; ! 514: bestaddr = stentry.n_value; ! 515: } ! 516: } ! 517: break; ! 518: ! 519: case N_SO: ! 520: goto ret; ! 521: ! 522: case N_SOL: ! 523: p = file; ! 524: for (;;) { ! 525: for (i=0; i<8; i++) { ! 526: if (*p != stentry.n_name[i]) goto neq; ! 527: if (*p++ == '\0') break; ! 528: } ! 529: if (stentry.n_name[7] == '\0') ! 530: break; ! 531: if (bread(&sbuf, &stentry, sizeof stentry) ! 532: < sizeof stentry) ! 533: error("Bad N_SO entry (1)"); ! 534: if ((stentry.n_type & STABMASK) != ! 535: (unsigned char) N_SOL) ! 536: error("Bad N_SO entry (2)"); ! 537: } ! 538: ignore = 0; ! 539: break; ! 540: ! 541: neq: ignore++; ! 542: break; ! 543: } ! 544: if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry) ! 545: break; ! 546: } ! 547: ret: return(bestln == BIGNUM ? -1 : bestaddr); ! 548: } ! 549: ! 550: /* gets address of proc:number */ ! 551: getaddr(proc,integ) ! 552: char *proc; { ! 553: register long offset; ! 554: register char *s, *f; ! 555: ADDR addr; ! 556: ! 557: s = proc[0] ? proc : curfile; ! 558: if (*s == '\0') ! 559: return(-1); ! 560: offset = nametooffset(s); ! 561: f = nametofile(s); ! 562: if (debug) printf("getaddr() computed offset %d", offset); ! 563: if (offset == -1) { ! 564: addr = extaddr(proc); ! 565: if (addr != -1) addr += 2; /* MACHINE DEPENDENT */ ! 566: if (debug) printf(" extaddr computed %d\n", addr); ! 567: return(addr); ! 568: } ! 569: if (integ) ! 570: addr = lntoaddr(integ, offset, s); ! 571: else { ! 572: addr = findproc(proc)->paddr + 2; /* MACHINE DEPENDENT */ ! 573: addr = lntoaddr(adrtolineno(addr)+1, offset, f); ! 574: } ! 575: if (debug) printf(" and addr %d\n", addr); ! 576: if (addr == -1) return(-1); ! 577: return(addr); ! 578: } ! 579: ! 580: /* returns address of external */ ! 581: ADDR ! 582: extaddr(name) ! 583: char *name; { ! 584: struct nlist stentry; ! 585: blseek(&sbuf, extstart, 0); ! 586: ! 587: for (;;) { ! 588: if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry) ! 589: return(-1); ! 590: if (stentry.n_name[0] == '_' && ! 591: eqpatr(name, stentry.n_name+1, 1)) ! 592: return(stentry.n_value); ! 593: } ! 594: } ! 595: ! 596: /* find enclosing common blocks and fix up addresses */ ! 597: docomm(offset) ! 598: long offset; { ! 599: struct nlist stentry; ! 600: ! 601: for (;;) { ! 602: if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry) { ! 603: error("Bad common block"); ! 604: return; ! 605: } ! 606: sl_class = N_GSYM; ! 607: if ((stentry.n_type & STABMASK) == N_ECOMM) { ! 608: sl_addr += extaddr(stentry.n_name); ! 609: blseek(&sbuf, offset, 0); ! 610: return; ! 611: } ! 612: if ((stentry.n_type & STABMASK) == N_ECOML) { ! 613: sl_addr += stentry.n_value; ! 614: blseek(&sbuf, offset, 0); ! 615: return; ! 616: } ! 617: } ! 618: } ! 619: ! 620: /* determine if class is that of a variable */ ! 621: char pctypes[] = {N_GSYM, N_STSYM, N_LCSYM, N_RSYM, N_SSYM, N_LSYM, ! 622: N_PSYM, 0}; ! 623: varclass(class) ! 624: char class; { ! 625: char *p; ! 626: ! 627: for (p=pctypes; *p; p++) { ! 628: if (class == *p) ! 629: return(1); ! 630: } ! 631: return(0); ! 632: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.