|
|
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.