|
|
1.1 ! root 1: /* ! 2: * trace6.c ! 3: * ! 4: * The information contained herein is a trade secret of Mark Williams ! 5: * Company, and is confidential information. It is provided under a ! 6: * license agreement, and may be copied or disclosed only under the ! 7: * terms of that agreement. Any reproduction or disclosure of this ! 8: * material without the express written authorization of Mark Williams ! 9: * Company or persuant to the license agreement is unlawful. ! 10: * ! 11: * COHERENT Version 2.3.35 ! 12: * Copyright (c) 1982, 1983, 1984. ! 13: * An unpublished work by Mark Williams Company, Chicago. ! 14: * All rights reserved. ! 15: * ! 16: * Miscellaneous routines. ! 17: */ ! 18: #include <stdio.h> ! 19: #include <ctype.h> ! 20: #include <canon.h> ! 21: #include <l.out.h> ! 22: #include "trace.h" ! 23: ! 24: #define MYPRINTF(x) printf(x) ! 25: #define DEBUG 0 ! 26: ! 27: unsigned short getMagic(); ! 28: caddr_t initn(); ! 29: off_t initb(); ! 30: off_t incb(); ! 31: off_t incb(); ! 32: off_t getseekoff(); ! 33: ! 34: /* ! 35: * Save the rest of the input line in `miscbuf'. If line is ! 36: * not given, save the default, `cp'. ! 37: */ ! 38: getline(cp) ! 39: register char *cp; ! 40: { ! 41: register int c; ! 42: register char *bp; ! 43: ! 44: bp = miscbuf; ! 45: if ((c=getn()) != '\n') { ! 46: while (c != '\n') { ! 47: if (c == '\\') ! 48: if ((c=getn())!='\n' && c!='\\') ! 49: *bp++ = '\\'; ! 50: *bp++ = c; ! 51: c = getn(); ! 52: } ! 53: } else { ! 54: while (*cp != '\0') ! 55: *bp++ = *cp++; ! 56: } ! 57: *bp++ = '\n'; ! 58: *bp = '\0'; ! 59: } ! 60: ! 61: /* ! 62: * Add a string onto the input stream. ! 63: * Make a node for string "cp" and insert it at the front of "inpp". ! 64: */ ! 65: addstrp(cp) ! 66: char *cp; ! 67: { ! 68: register INP *ip; ! 69: ! 70: ip = nalloc(sizeof (INP)); ! 71: ip->i_st2.i_next = inpp; ! 72: ip->i_st2.i_type = ICORE; ! 73: ip->i_st2.i_strp = cp; ! 74: inpp = ip; ! 75: } ! 76: ! 77: /* ! 78: * Add a file pointer onto the input stack. ! 79: */ ! 80: addfilp(fp) ! 81: FILE *fp; ! 82: { ! 83: register INP *ip; ! 84: ! 85: ip = nalloc(sizeof (INP)); ! 86: ip->i_st1.i_next = inpp; ! 87: ip->i_st1.i_type = IFILE; ! 88: ip->i_st1.i_filp = fp; ! 89: inpp = ip; ! 90: } ! 91: ! 92: /* ! 93: * Get the next character from the input stream. ! 94: */ ! 95: getn() ! 96: { ! 97: register INP *ip; ! 98: register int c; ! 99: ! 100: if (lastc != '\0') { ! 101: c = lastc; ! 102: lastc = '\0'; ! 103: return (c); ! 104: } ! 105: while ((ip=inpp) != NULL) { ! 106: switch (ip->i_st1.i_type) { ! 107: case ICORE: ! 108: if ((c=*ip->i_st2.i_strp++) != '\0') ! 109: return (c); ! 110: break; ! 111: case IFILE: ! 112: if ((c=getc(ip->i_st1.i_filp)) != EOF) ! 113: return (c); ! 114: if (ip->i_st1.i_filp == stdin) { ! 115: if (testint()) ! 116: continue; ! 117: leave(); ! 118: } ! 119: fclose(ip->i_st1.i_filp); ! 120: break; ! 121: } ! 122: inpp = inpp->i_st1.i_next; ! 123: nfree(ip); ! 124: } ! 125: return (EOF); ! 126: } ! 127: ! 128: /* ! 129: * Put back a character onto the current input stream. ! 130: */ ! 131: ungetn(c) ! 132: { ! 133: lastc = c; ! 134: } ! 135: ! 136: /* ! 137: * Put out an address. `t' is the tolerance allowed. ! 138: */ ! 139: putaddr(s, l, t) ! 140: long l; ! 141: { ! 142: register char *sp; ! 143: ! 144: sp = conaddr(miscbuf, s, l, t); ! 145: *sp = '\0'; ! 146: printx("%s", miscbuf); ! 147: } ! 148: ! 149: /* ! 150: * Read `n' bytes from the current position in segment `seg' ! 151: * and store it in the buffer `bp'. ! 152: */ ! 153: getb(segn, bp, n) ! 154: char *bp; ! 155: unsigned n; ! 156: { ! 157: if (getputb(segn, bp, n, 0) == 0) ! 158: return (0); ! 159: canon(bp, n); ! 160: ! 161: #if DEBUG ! 162: { ! 163: int i; ! 164: for (i=0; i<n; i++) printf("bp = %x\n", (unsigned char)bp[i]); ! 165: } ! 166: #endif ! 167: return (1); ! 168: } ! 169: ! 170: /* ! 171: * Put `n' bytes from the buffer `bp' into segment `seg'. ! 172: */ ! 173: putb(segn, bp, n) ! 174: char *bp; ! 175: unsigned n; ! 176: { ! 177: canon(bp, n); ! 178: return (getputb(segn, bp, n, 1)); ! 179: } ! 180: ! 181: /* ! 182: * Canonize the buffer `bp' of length `n' according to `cantype'. ! 183: */ ! 184: canon(bp, n) ! 185: register char *bp; ! 186: unsigned n; ! 187: { ! 188: register int i; ! 189: register int t; ! 190: ! 191: if (cantype == 1) { ! 192: if ((n&1) != 0) ! 193: return; ! 194: for (i=0; i<n; i+=2) { ! 195: t = bp[i]; ! 196: bp[i] = bp[i+1]; ! 197: bp[i+1] = t; ! 198: } ! 199: } ! 200: } ! 201: ! 202: /* ! 203: * Move `n' bytes between the buffer `bp' and the segment `segn'. ! 204: * The flag `d' controls the direction. ! 205: */ ! 206: getputb(segn, bp, n, d) ! 207: char *bp; ! 208: unsigned n; ! 209: { ! 210: register MAP *mp; ! 211: register unsigned l; ! 212: register unsigned s; ! 213: register int (*f)(); ! 214: off_t a; ! 215: ! 216: s = n; ! 217: a = add; ! 218: while (s) { ! 219: if ((mp=mapaddr(segn, a)) == NULL) { ! 220: return 0; ! 221: } ! 222: l = s; ! 223: if (a+l > mp->m_bend) ! 224: l = mp->m_bend-a+1; ! 225: f = d ? mp->m_putf : mp->m_getf; ! 226: if ((*f)(mp->m_segi, mp->m_offt+(a-mp->m_base), bp, l) == 0) { ! 227: return 0; ! 228: } ! 229: bp += l; ! 230: a += l; ! 231: s -= l; ! 232: } ! 233: add += n; ! 234: return (1); ! 235: } ! 236: ! 237: /* ! 238: * Given a segment number and an address, return the segment map ! 239: * in which the address falls. ! 240: */ ! 241: MAP * ! 242: mapaddr(n, a) ! 243: off_t a; ! 244: { ! 245: register MAP *mp; ! 246: ! 247: for (mp=segmapl[n]; mp; mp=mp->m_next) { ! 248: if (mp->m_base<=a && a<mp->m_bend) ! 249: break; ! 250: } ! 251: return (mp); ! 252: } ! 253: ! 254: /* ! 255: * Read a symbol and return its value in the given `VAL' structure. ! 256: */ ! 257: getsval(vp) ! 258: VAL *vp; ! 259: { ! 260: register int n; ! 261: register int c; ! 262: struct LDSYM lds; ! 263: ! 264: n = 0; ! 265: c = getn(); ! 266: while (isascii(c) && (isalnum(c)||c=='_')) { ! 267: if (n < NCPLN) ! 268: lds.ls_id[n++] = c; ! 269: c = getn(); ! 270: } ! 271: ungetn(c); ! 272: while (n < NCPLN) ! 273: lds.ls_id[n++] = '\0'; ! 274: if (specsym(&lds)==0 && regaddr(&lds)==0 && nameval(&lds)==0) { ! 275: printe("Symbol not found"); ! 276: return (0); ! 277: } ! 278: switch (lds.ls_type&LR_SEG) { ! 279: case L_SHRI: ! 280: case L_PRVI: ! 281: case L_BSSI: ! 282: vp->v_segn = 1; ! 283: vp->v_flag = VLVAL; ! 284: break; ! 285: case L_SHRD: ! 286: case L_PRVD: ! 287: case L_BSSD: ! 288: case L_ABS: ! 289: vp->v_segn = 0; ! 290: vp->v_flag = VLVAL; ! 291: break; ! 292: ! 293: case L_REF: ! 294: printe("Symbol not defined"); ! 295: return (0); ! 296: case L_REG: ! 297: vp->v_segn = 2; ! 298: vp->v_flag = VLVAL; ! 299: break; ! 300: } ! 301: vp->v_nval = lds.ls_addr; ! 302: return (1); ! 303: } ! 304: ! 305: /* ! 306: * See if the given symbol is a special symbol. ! 307: */ ! 308: specsym(ldp) ! 309: register struct LDSYM *ldp; ! 310: { ! 311: if (ldp->ls_id[1] != '\0') ! 312: return (0); ! 313: switch (ldp->ls_id[0]) { ! 314: case 'd': ! 315: ldp->ls_type = L_SHRD; ! 316: break; ! 317: case 'i': ! 318: ldp->ls_type = L_SHRI; ! 319: break; ! 320: case 'u': ! 321: ldp->ls_type = L_REG; ! 322: break; ! 323: default: ! 324: return (0); ! 325: } ! 326: ldp->ls_addr = 0; ! 327: return (1); ! 328: } ! 329: ! 330: /* ! 331: * Convert a value to an address. `t' is the tolerance ! 332: * allowed. ! 333: */ ! 334: char * ! 335: conaddr(sp, s, l, t) ! 336: register char *sp; ! 337: unsigned long l; ! 338: { ! 339: /* Bug in PDP11 compiler ! 340: register unsigned d; ! 341: */ ! 342: unsigned d; ! 343: struct LDSYM ldsym; ! 344: ! 345: ! 346: /* Bug in 8086 compiler ! 347: if (t<0 || valname(s, l, &ldsym)==0 || (d=l-ldsym.ls_addr)>t) ! 348: */ ! 349: if (t<0 || valname(s, l, &ldsym)==0 || ! 350: (d=(unsigned)l-ldsym.ls_addr)>t) ! 351: concons(sp, l); ! 352: else { ! 353: sprintf(sp, "%.*s", NCPLN, ldsym.ls_id); ! 354: while (*sp) ! 355: sp++; ! 356: if (d != 0) { ! 357: *sp++ = '+'; ! 358: sprintf(sp, "%u", d); ! 359: } ! 360: } ! 361: while (*sp) ! 362: sp++; ! 363: return (sp); ! 364: } ! 365: ! 366: /* ! 367: * Find the value of a symbol. ! 368: */ ! 369: nameval(ldp) ! 370: struct LDSYM *ldp; ! 371: { ! 372: register int u; ! 373: register caddr_t n; ! 374: register SYM *sp; ! 375: register int r; ! 376: register int h; ! 377: register off_t b; ! 378: struct LDSYM lds; ! 379: struct LDSYM ldu; ! 380: ! 381: u = 0; ! 382: h = hash(ldp); ! 383: evalhdrinfo(lfp); ! 384: for (n=initn(), sp=ssymp, b=initb(); n-- ! 385: ; sp++, b=incb(b, ((caddr_t)sngblsym-n))) { ! 386: if (ssymp!=NULL && sp->s_hash!=h) { ! 387: continue; ! 388: } ! 389: ! 390: if (hdrinfo.magic == L_MAGIC) { ! 391: if (!rdldSym(sfp, (long)b, &lds)) ! 392: return(0); ! 393: } ! 394: else ! 395: if (!rdcoff_to_loutSym(sfp, (long)b, &lds)) ! 396: return(0); ! 397: ! 398: if ((r=namecmp(ldp, &lds)) > 0) { ! 399: *ldp = lds; ! 400: return (1); ! 401: } ! 402: if (r < 0) { ! 403: ldu = lds; ! 404: u = 1; ! 405: } ! 406: } ! 407: if (u) { ! 408: *ldp = ldu; ! 409: return (1); ! 410: } ! 411: return (0); ! 412: } ! 413: ! 414: /* ! 415: * Compare the names of two symbol table entries. If the compare ! 416: * fails and the name of the first entry doesn't already end with ! 417: * an '_', the compare is effectively tried again after appending ! 418: * an '_', to the end of the first symbol name. ! 419: */ ! 420: namecmp(ldp1, ldp2) ! 421: struct LDSYM *ldp1; ! 422: struct LDSYM *ldp2; ! 423: { ! 424: register char *cp1; ! 425: register char *cp2; ! 426: register int n; ! 427: ! 428: n = CCSSIZE; ! 429: cp1 = ldp1->ls_id; ! 430: cp2 = ldp2->ls_id; ! 431: do { ! 432: if (*cp1 != *cp2++) { ! 433: if (*cp2!='\0' || *--cp2!='_') ! 434: return (0); ! 435: if (*cp1!='\0' || *--cp1=='_') ! 436: return (0); ! 437: return (-1); ! 438: } ! 439: if (*cp1++ == '\0') ! 440: return (1); ! 441: } while (--n); ! 442: return (1); ! 443: } ! 444: ! 445: #define NEW 1 ! 446: ! 447: /* ! 448: * Given a value, find the closest symbol below. ! 449: */ ! 450: valname(s, m, ldp) ! 451: off_t m; ! 452: struct LDSYM *ldp; ! 453: { ! 454: register int n; ! 455: register off_t a; ! 456: register SYM *sp; ! 457: register int t; ! 458: register int n1; ! 459: register off_t a1; ! 460: struct LDSYM lds; ! 461: off_t b, seekoff; ! 462: ! 463: strncpy(ldp->ls_id, "", NCPLN); ! 464: if (sfp == NULL) ! 465: return (0); ! 466: a1 = 0; ! 467: n1 = -1; ! 468: if (ssymp == NULL) ! 469: fseek(sfp, (long)sbase, 0); ! 470: hdrinfo.magic = getMagic(lfp); ! 471: for (n=0, sp=ssymp, b=initb(); n<initn() ! 472: ; n++, sp++, b=incb(b, ((caddr_t)n))) { ! 473: if (ssymp != NULL) { ! 474: a = sp->s_sval; ! 475: t = sp->s_type; ! 476: } ! 477: else { ! 478: if (hdrinfo.magic == L_MAGIC) { ! 479: if (!rdldSym(sfp, (long)b, &lds)) ! 480: return(0); ! 481: } ! 482: else { ! 483: if (!rdcoff_to_loutSym(sfp, (long)b, &lds)) ! 484: return(0); ! 485: } ! 486: a = (off_t)lds.ls_addr; ! 487: t = lds.ls_type; ! 488: } ! 489: if (hdrinfo.magic == L_MAGIC) { ! 490: switch (t&LR_SEG) { ! 491: case L_SHRI: ! 492: case L_PRVI: ! 493: case L_BSSI: ! 494: if (s == 0) ! 495: continue; ! 496: break; ! 497: case L_SHRD: ! 498: case L_PRVD: ! 499: case L_BSSD: ! 500: if (s == 1) ! 501: continue; ! 502: break; ! 503: default: ! 504: continue; ! 505: } ! 506: } ! 507: if ( ((unsigned long)a <= (unsigned long)m) ) { ! 508: if (a1==0 || (unsigned long)a > (unsigned long)a1) { ! 509: a1 = a; ! 510: n1 = n; ! 511: } ! 512: } ! 513: } ! 514: ! 515: if (n1 >= 0) { ! 516: seekoff = sbase + getseekoff(n1); ! 517: if (hdrinfo.magic == L_MAGIC) { ! 518: if (!rdldSym(sfp, seekoff, ldp)) ! 519: return(0); ! 520: } ! 521: else { ! 522: if (!rdcoff_to_loutSym(sfp, seekoff, ldp)) ! 523: return(0); ! 524: } ! 525: return (1); ! 526: } ! 527: return (0); ! 528: } ! 529: ! 530: rdldSym(fp, seekoff, LDSP) ! 531: FILE *fp; ! 532: long seekoff; ! 533: struct LDSYM *LDSP; ! 534: { ! 535: register int i; ! 536: struct ldsym lds; ! 537: ! 538: fseek(fp, seekoff, 0); ! 539: if (fread(&lds, sizeof(struct ldsym), 1, fp) != 1) ! 540: return (0); ! 541: canint(lds.ls_type); ! 542: canvaddr(lds.ls_addr); ! 543: for (i=0; i<NCPLN; i++) ! 544: LDSP->ls_id[i] = lds.ls_id[i]; ! 545: LDSP->ls_type = lds.ls_type; ! 546: LDSP->ls_addr = (long)lds.ls_addr; ! 547: return(1); ! 548: } ! 549: ! 550: /* ! 551: * Read `n' bytes from the file specified by `f' starting at ! 552: * address `seek'. ! 553: */ ! 554: getf(f, seek, bp, n) ! 555: long seek; ! 556: char *bp; ! 557: { ! 558: register FILE *fp; ! 559: ! 560: fp = f ? cfp : lfp; ! 561: fseek(fp, (long)seek, 0); ! 562: return (fread(bp, n, 1, fp)); ! 563: } ! 564: ! 565: /* ! 566: * Write `n' bytes into the files specified by `f' starting at ! 567: * address `seek'. ! 568: */ ! 569: putf(f, seek, bp, n) ! 570: long seek; ! 571: char *bp; ! 572: { ! 573: register FILE *fp; ! 574: int ret = 1; ! 575: ! 576: fp = f ? cfp : lfp; ! 577: fseek(fp, (long)seek, 0); ! 578: if (fwrite(bp, n, 1, fp) != 1) { ! 579: ret = 0; ! 580: } ! 581: if (ret) { ! 582: if (fflush(fp)!=EOF) { ! 583: ret = 0; ! 584: } ! 585: } ! 586: return ret; ! 587: } ! 588: ! 589: /* ! 590: * Allocate `n' bytes. ! 591: */ ! 592: char * ! 593: nalloc(n) ! 594: { ! 595: register char *cp; ! 596: ! 597: if ((cp=malloc(n)) == NULL) ! 598: panic("No memory"); ! 599: return (cp); ! 600: } ! 601: ! 602: /* ! 603: * Free up storage. ! 604: */ ! 605: nfree(cp) ! 606: char *cp; ! 607: { ! 608: free(cp); ! 609: } ! 610: ! 611: /* ! 612: * Print out an error message and exit. ! 613: */ ! 614: panic(a1) ! 615: char *a1; ! 616: { ! 617: fprintf(stderr, "%r", &a1); ! 618: putc('\n', stderr); ! 619: exit(1); ! 620: } ! 621: ! 622: /* ! 623: * Print out a breakpoint error message. ! 624: */ ! 625: printb(a) ! 626: caddr_t a; ! 627: { ! 628: fprintf(stderr, "Breakpoint error at "); ! 629: fprintf(stderr, DAFMT, (long)a); ! 630: putc('\n', stderr); ! 631: } ! 632: ! 633: /* ! 634: * Print out a fatal error message. ! 635: */ ! 636: printr(a1) ! 637: char *a1; ! 638: { ! 639: fprintf(stderr, "%r", &a1); ! 640: putc('\n', stderr); ! 641: } ! 642: ! 643: /* ! 644: * Print out an error message. ! 645: */ ! 646: printe(sp) ! 647: char *sp; ! 648: { ! 649: errrstr = sp; ! 650: fprintf(stderr, "%s?\n", errrstr); ! 651: } ! 652: ! 653: /* ! 654: * Print formatted. ! 655: */ ! 656: printx(a1) ! 657: char *a1; ! 658: { ! 659: printf("%r", &a1); ! 660: } ! 661: ! 662: /* ! 663: * Put out a character. ! 664: */ ! 665: putx(c) ! 666: { ! 667: putchar(c); ! 668: } ! 669: ! 670: ! 671: /****************************************************************************** ! 672: * ! 673: * Note some #defines in these include files interferes with ! 674: * items in preceeding include files. Hence the strange ! 675: * program order. ! 676: * ! 677: ******************************************************************************/ ! 678: ! 679: #include <coff.h> ! 680: ! 681: static FILEHDR coffh; ! 682: ! 683: evalhdrinfo(fp) ! 684: FILE *fp; ! 685: { ! 686: hdrinfo.magic = getMagic(fp); ! 687: if (hdrinfo.magic == C_386_MAGIC) ! 688: hdrinfo.defsegatt = DSA32; ! 689: else ! 690: hdrinfo.defsegatt = DSA16; ! 691: } ! 692: ! 693: unsigned short ! 694: getMagic(fp) ! 695: FILE *fp; ! 696: { ! 697: fseek(fp,0L,0); ! 698: if ( fread(&coffh, sizeof(FILEHDR), 1, fp) != 1 ) ! 699: panic("Cannot read object file"); ! 700: if (coffh.f_magic == C_386_MAGIC) ! 701: return(C_386_MAGIC); ! 702: else { ! 703: canint(coffh.f_magic); ! 704: if ( coffh.f_magic == L_MAGIC ) ! 705: return(L_MAGIC); ! 706: else ! 707: panic("Bad object file"); ! 708: } ! 709: return(0); ! 710: } ! 711: ! 712: rdcoff_to_loutSym(fp, seekoff, ldsp) ! 713: FILE *fp; ! 714: long seekoff; ! 715: struct LDSYM *ldsp; ! 716: { ! 717: SYMENT coffsym; ! 718: char *str_tabp; ! 719: SCNHDR *scnhp; ! 720: ! 721: str_tabp = (char *)read_str_tab(fp, snsym, sbase); ! 722: ! 723: fseek(fp, seekoff, 0); ! 724: if (fread(&coffsym, sizeof(SYMENT), 1, fp) != 1) { ! 725: printf("Unable to read coff symbols\n"); ! 726: return(0); ! 727: } ! 728: ! 729: scnhp = (SCNHDR *)read_scns(fp, coffh.f_nscns ! 730: , sizeof(FILEHDR)+coffh.f_opthdr); ! 731: if (scnhp == NULL) { ! 732: printf("Unable to read section headers\n"); ! 733: return(0); ! 734: } ! 735: ! 736: coff_to_lout(&coffsym, ldsp, str_tabp, scnhp); ! 737: ! 738: nfree(str_tabp); ! 739: nfree(scnhp); ! 740: return(1); ! 741: } ! 742: ! 743: ! 744: caddr_t ! 745: initn() ! 746: { ! 747: ! 748: return(hdrinfo.magic == C_386_MAGIC ? (caddr_t)sngblsym : (caddr_t)snsym); ! 749: } ! 750: ! 751: off_t ! 752: initb() ! 753: { ! 754: off_t b; ! 755: ! 756: b = (hdrinfo.magic == C_386_MAGIC ! 757: ? ( sbase+(gblsymMap[0]*(off_t)sizeof(SYMENT)) ) ! 758: : sbase); ! 759: return(b); ! 760: } ! 761: ! 762: off_t ! 763: incb(b, i) ! 764: off_t b; ! 765: int i; ! 766: { ! 767: b += ( hdrinfo.magic == C_386_MAGIC ! 768: ? ( (gblsymMap[i] - gblsymMap[i-1L]) * sizeof(SYMENT) ) ! 769: : sizeof(struct ldsym) ); ! 770: return(b); ! 771: } ! 772: ! 773: off_t ! 774: getseekoff(n1) ! 775: { ! 776: off_t b; ! 777: ! 778: b = ( hdrinfo.magic == C_386_MAGIC ! 779: ? ( (gblsymMap[n1]) * sizeof(SYMENT) ) ! 780: : (n1 * sizeof(struct ldsym)) ); ! 781: return(b); ! 782: } ! 783: ! 784: /* end of trace6.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.