|
|
1.1 root 1: /*
2: * trace1.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: * Initialization, command line parsing.
17: */
18: #include <stdio.h>
19: #include <ctype.h>
20: #include <canon.h>
21: #include <l.out.h>
22: #include <sys/timeout.h>
23: #include <sys/proc.h>
24: #include <sys/ptrace.h>
25: #include <signal.h>
26: #include <sys/uproc.h>
27: #include "trace.h"
28:
29: static char *symName();
30:
31: main(argc, argv)
32: char **argv;
33: {
34: initialise();
35: setup(argc, argv);
36: signal(SIGINT, &armsint);
37: signal(SIGQUIT, SIG_IGN);
38: process();
39: }
40:
41: /*
42: * Leave.
43: */
44: leave()
45: {
46: nfree(ssymp);
47: nfree(gblsymMap);
48: killc();
49: exit(0);
50: }
51:
52: /*
53: * Initialize segment formats and clear the breakpoint table.
54: */
55: initialise()
56: {
57: strcpy(segform[DSEG], "w");
58: strcpy(segform[ISEG], "i");
59: strcpy(segform[USEG], "w");
60: bptinit();
61: }
62:
63: /*
64: * Setup arguments.
65: */
66: setup(argc, argv)
67: char **argv;
68: {
69: register char *cp;
70: register int c;
71: register int t;
72: register int u;
73: register int tflag;
74:
75: t = '\0';
76: tflag = 0;
77:
78: /* process command line switches -[cdefkorst] */
79: for (; argc>1; argc--, argv++) {
80: cp = argv[1];
81: if (*cp++ != '-')
82: break;
83: while ((c=*cp++) != '\0') {
84: switch (c) {
85: case 'c':
86: case 'd':
87: case 'e':
88: case 'f':
89: case 'k':
90: case 'o':
91: /* only one of [cdefko] is allowed */
92: if (t != '\0')
93: usage();
94: t = c;
95: continue;
96: case 'r':
97: rflag = 1;
98: continue;
99: case 's':
100: sflag = 1;
101: continue;
102: case 't':
103: tflag = 1;
104: continue;
105: default:
106: usage();
107: }
108: }
109: }
110: switch (t) {
111: case '\0':
112: switch (argc) {
113: case 1:
114: setfh(DEFLT_OBJ, 3);
115: setcore(DEFLT_AUX);
116: break;
117: case 2:
118: setfh(argv[1], 3);
119: break;
120: case 3:
121: setfh(argv[1], 3);
122: setcore(argv[2]);
123: break;
124: default:
125: usage();
126: }
127: break;
128: case 'c':
129: switch (argc) {
130: case 1:
131: setfh(DEFLT_OBJ, 3);
132: setcore(DEFLT_AUX);
133: break;
134: case 2:
135: setcore(argv[1]);
136: break;
137: case 3:
138: setfh(argv[1], 3);
139: setcore(argv[2]);
140: break;
141: default:
142: usage();
143: }
144: break;
145: case 'd':
146: switch (argc) {
147: case 1:
148: setfh("/coherent", 3);
149: setdump("/dev/dump");
150: break;
151: case 3:
152: setfh(argv[1], 3);
153: setdump(argv[2]);
154: break;
155: default:
156: usage();
157: }
158: break;
159: case 'e':
160: if (argc < 2)
161: usage();
162: setfh(argv[1], 3);
163: if (startup(&argv[1], NULL, NULL, 0)==0 || shiftup()==0)
164: leave();
165: break;
166: case 'f':
167: switch (argc) {
168: case 2:
169: setfile(argv[1]);
170: break;
171: case 3:
172: setfh(argv[1], 1);
173: setfile(argv[2]);
174: break;
175: default:
176: usage();
177: }
178: break;
179: case 'k':
180: switch (argc) {
181: case 1:
182: setfh("/coherent", 1);
183: setkmem("/dev/mem");
184: break;
185: case 2:
186: setkmem(argv[1]);
187: break;
188: case 3:
189: setfh(argv[1], 1);
190: setkmem(argv[2]);
191: break;
192: default:
193: usage();
194: }
195: break;
196: case 'o':
197: switch (argc) {
198: case 1:
199: setfh(DEFLT_OBJ, 3);
200: break;
201: case 2:
202: setfh(argv[1], 3);
203: break;
204: case 3:
205: setfh(argv[1], 1);
206: setfh(argv[2], 2);
207: break;
208: default:
209: usage();
210: }
211: }
212: if (tflag) {
213: if ((u=open("/dev/tty", 2)) < 0)
214: panic("Cannot open /dev/tty");
215: dup2(u, 0);
216: dup2(u, 1);
217: dup2(u, 2);
218: }
219: }
220:
221: /*
222: * Generate a usage message.
223: */
224: usage()
225: {
226: panic("Usage: db [-cdefort] [object file] [auxiliary file]");
227: }
228:
229: /*
230: * Catch and flag interrupts.
231: */
232: armsint()
233: {
234: signal(SIGINT, &armsint);
235: intflag++;
236: }
237:
238: /*
239: * Check for interrupts and clear flag.
240: */
241: testint()
242: {
243: register int n;
244:
245: if ((n=intflag) != 0)
246: printe("Interrupt");
247: intflag = 0;
248: return (n);
249: }
250:
251: /*
252: * Assume the file, `np', is the name of an l.out. If the bottom bit
253: * of the flag is set, set up the symbol table. If the next bit is set,
254: * set up segmentation for the l.out.
255: */
256: setlout(np, f)
257: char *np;
258: {
259: struct ldheader ldh;
260:
261: fseek(lfp, 0L, 0L);
262: if (fread(&ldh, sizeof(ldh), 1, lfp) != 1)
263: panic("Cannot read object file");
264: canlout(&ldh);
265: if (ldh.l_magic != L_MAGIC)
266: panic("Bad object file");
267: hdrinfo.magic = ldh.l_magic;
268: hdrinfo.defsegatt = DSA16;
269: objflag = 1;
270: if ((f&1) != 0) {
271: sbase = sizeof(ldh);
272: sbase += ldh.l_ssize[L_SHRI] + ldh.l_ssize[L_PRVI];
273: sbase += ldh.l_ssize[L_SHRD] + ldh.l_ssize[L_PRVD];
274: snsym = ldh.l_ssize[L_SYM] / sizeof(struct ldsym);
275: if (snsym != 0) {
276: sfp = lfp;
277: if (sflag == 0)
278: readsym(sfp);
279: }
280: }
281: if ((f&2) != 0) {
282: lfn = np;
283: setaseg(&ldh);
284: }
285: }
286:
287: /*
288: * Canonicalize an l.out header.
289: */
290: canlout(ldp)
291: struct ldheader *ldp;
292: {
293: register int i;
294:
295: canint(ldp->l_magic);
296: canint(ldp->l_flag);
297: canint(ldp->l_machine);
298: canvaddr(ldp->l_entry);
299: for (i=0; i<NLSEG; i++)
300: cansize(ldp->l_ssize[i]);
301: }
302:
303: /*
304: * Read all global symbols into memory.
305: */
306: readsym(fp)
307: FILE *fp;
308: {
309: register int n, i;
310: register SYM *sp;
311: struct ldsym lds;
312: struct LDSYM LDS;
313:
314: if ((ssymp=nalloc((int)snsym * sizeof(SYM))) == NULL)
315: return;
316: fseek(fp, (long)sbase, 0);
317: for (n=snsym, sp=ssymp; n--; sp++) {
318: if (fread(&lds, sizeof(struct ldsym), 1, fp) != 1) {
319: nfree(ssymp);
320: ssymp = NULL;
321: return;
322: }
323: canint(lds.ls_type);
324: canvaddr(lds.ls_addr);
325: for (i=0; i<NCPLN; i++)
326: LDS.ls_id[i] = lds.ls_id[i];
327: LDS.ls_type = lds.ls_type;
328: LDS.ls_addr = (long)lds.ls_addr;
329:
330: sp->s_hash = hash(&LDS);
331: sp->s_type = LDS.ls_type;
332: sp->s_sval = LDS.ls_addr;
333: }
334: }
335:
336: /*
337: * Hash a symbol name.
338: */
339: hash(ldp)
340: struct LDSYM *ldp;
341: {
342: register int h, n;
343: register char *cp;
344:
345: h = 0;
346: n = CCSSIZE;
347: cp = ldp->ls_id;
348: do {
349: if (*cp != '_')
350: h += *cp;
351: if (*cp++ == '\0')
352: break;
353: } while (--n);
354: return (h&0377);
355: }
356:
357: /*
358: * Set up segmentation for a core dump. The registers are also read.
359: */
360: setcore(np)
361: char *np;
362: {
363: register unsigned i;
364: register MAP *mp;
365: register char *cp;
366: register char *lcp;
367: register fsize_t size;
368: register fsize_t offt;
369: char ucomm[10];
370: SR usegs[NUSEG];
371:
372: cfp = openfil(np, rflag);
373: fseek(cfp, (long)offset(uproc, u_comm[0]), 0);
374: if ((cp=lfn)!=NULL && fread(ucomm, sizeof(ucomm), 1, cfp)==1) {
375: lcp = cp;
376: while (*cp) {
377: if (*cp++ == '/')
378: lcp = cp;
379: }
380: if (strncmp(lcp, ucomm, sizeof(ucomm)) != 0)
381: printr("Core different from object");
382: }
383: fseek(cfp, (long)offset(uproc, u_segl[0]), 0);
384: if (fread(usegs, sizeof(usegs), 1, cfp) != 1)
385: panic("Bad core file");
386: USPACE = setsmap(NULL, (fsize_t)0, (fsize_t)UPASIZE, (fsize_t)0,
387: getf, putf, 1);
388: mp = clrsmap(DSPACE, endpure);
389: offt = usegs[0].sr_size;
390: #ifdef _I386
391: usegs[SISTACK].sr_base -= usegs[SISTACK].sr_size;
392: #endif
393: for (i=1; i<NUSEG; i++) {
394: if (usegs[i].sr_segp == NULL)
395: continue;
396: if ((~usegs[i].sr_flag) & (SRFDUMP|SRFPMAP))
397: continue;
398: size = usegs[i].sr_size;
399: mp = setsmap(mp, (fsize_t)usegs[i].sr_base, size, offt,
400: getf, putf, 1);
401: offt += size;
402: }
403: if (ISPACE == DSPACE)
404: ISPACE = mp;
405: DSPACE = mp;
406: settrap();
407: setregs();
408: }
409:
410: /*
411: * Find out signal sent to traced process.
412: */
413: settrap()
414: {
415: int f;
416:
417: trapstr = "???";
418: add = PTRACE_SIG;
419: if (getb(USEG, (char *)&f, sizeof(f)) == 0) {
420: printr("Cannot read signal in traced process");
421: return 0;
422: }
423: if (f<=0 || f>NSIG) {
424: printr("Bad signal in traced process");
425: return 0;
426: }
427: trapstr = signame[f-1];
428: return f;
429: }
430:
431: /*
432: * Set up segmentation for an ordinary file.
433: * This is really easy.
434: */
435: setfile(np)
436: char *np;
437: {
438: lfp = openfil(np, rflag);
439: DSPACE = setsmap(NULL, (fsize_t)0, (fsize_t)LI, (fsize_t)0,
440: getf, putf, 0);
441: ISPACE = DSPACE;
442: }
443:
444: /*
445: * Open the given file. If `rflag' is set, the file is opened for
446: * read only.
447: */
448: FILE *
449: openfil(np, rflag)
450: char *np;
451: {
452: register FILE *fp;
453:
454: if (rflag) {
455: if ((fp=fopen(np, "r")) != NULL)
456: return (fp);
457: } else {
458: if ((fp=fopen(np, "r+w")) != NULL)
459: return (fp);
460: if ((fp=fopen(np, "r")) != NULL) {
461: printr("%s: opened read only", np);
462: return (fp);
463: }
464: }
465: panic("Cannot open %s", np);
466: }
467:
468: /*
469: * Initialise an element of a segment map.
470: */
471: MAP * setsmap(next, base, size, offt, getf, putf, segi)
472: MAP *next;
473: fsize_t base;
474: fsize_t size;
475: fsize_t offt;
476: int (*getf)();
477: int (*putf)();
478: {
479: register MAP *mp;
480:
481: mp = (MAP *)nalloc(sizeof(MAP));
482: mp->m_next = next;
483: mp->m_base = base;
484: mp->m_bend = base+size;
485: mp->m_offt = offt;
486: mp->m_getf = getf;
487: mp->m_putf = putf;
488: mp->m_segi = segi;
489: return (mp);
490: }
491:
492: /*
493: * Clear a section of a segment map.
494: */
495: MAP * clrsmap(mp, np)
496: register MAP *mp;
497: register MAP *np;
498: {
499: while (mp != np) {
500: nfree(mp);
501: mp = mp->m_next;
502: }
503: return (mp);
504: }
505:
506: /*
507: * Clear all maps.
508: */
509: clramap()
510: {
511: register int n;
512:
513: n = 0;
514: if (segmapl[0] == segmapl[1])
515: segmapl[n++] = NULL;
516: while (n < NSEGM) {
517: segmapl[n] = clrsmap(segmapl[n], NULL);
518: n++;
519: }
520: }
521:
522:
523: /******************************************************************************
524: *
525: * Note some #defines in these include files interferes with
526: * items in preceeding include files. Hence the strange
527: * program order.
528: *
529: ******************************************************************************/
530:
531: #include <coff.h>
532:
533: char *read_str_tab();
534: SCNHDR *read_scns();
535:
536: /*
537: * Setup object file.
538: *
539: * Arguments:
540: * np = file name
541: * f is bit mapped
542: * set 1's bit if reading symbol table info from file "np"
543: * set 2's bit if reading segment info from file "np"
544: */
545: setfh (np,f)
546: char *np;
547: {
548: FILEHDR coffh;
549:
550: lfp = openfil(np, (f&2) ? rflag : 1);
551: if (fread(&coffh, sizeof(coffh), 1, lfp) != 1)
552: panic("Cannot read object file");
553: if (coffh.f_magic == C_386_MAGIC)
554: setcoff(lfp, &coffh, np, f);
555: else setlout(np, f);
556: }
557:
558: setcoff(fp, coffhp, np, f)
559: FILE *fp;
560: FILEHDR *coffhp;
561: char *np;
562: int f;
563: {
564: hdrinfo.magic = coffhp->f_magic;
565: hdrinfo.defsegatt = DSA32;
566: objflag = 1;
567: if (f&1) {
568: if (coffhp->f_nsyms) {
569: sbase = (fsize_t)coffhp->f_symptr;
570: snsym = (fsize_t)coffhp->f_nsyms;
571: if (snsym != 0L) {
572: sfp = fp;
573: if (sflag == 0) {
574: readCoffSym(fp, coffhp);
575: }
576: }
577: }
578: }
579: if (f&2) {
580: lfn = np;
581: setcoffseg(fp, coffhp);
582: }
583: }
584:
585: readCoffSym(fp, coffhp)
586: FILE *fp;
587: FILEHDR *coffhp;
588: {
589: SYMENT coffsym;
590: struct LDSYM lds;
591: SYM *sp;
592: long n;
593: char *str_tabp;
594: SCNHDR *scnhp;
595:
596:
597: str_tabp = read_str_tab(fp, coffhp->f_nsyms, coffhp->f_symptr);
598:
599: scnhp = read_scns(fp, coffhp->f_nscns
600: , sizeof(FILEHDR)+coffhp->f_opthdr);
601:
602: /* could get entry point here FIX 386 */
603:
604: if (scnhp == NULL)
605: return;
606:
607: if ((gblsymMap=nalloc((int)coffhp->f_nsyms * sizeof(off_t))) == NULL) {
608: printf("Not enough memory for the global symbol map.\n");
609: return;
610: }
611: if ((ssymp=nalloc((int)coffhp->f_nsyms * sizeof(SYM))) == NULL) {
612: printf("Not enough memory for the coff symbol header section.\n");
613: return;
614: }
615:
616: fseek(fp, coffhp->f_symptr, 0);
617:
618: for (n=coffhp->f_nsyms, sp=ssymp; n--; ) {
619: if (fread(&coffsym, sizeof(SYMENT), 1, fp) != 1) {
620: printf("Cannot read coff.h symbols\n");
621: nfree(ssymp);
622: ssymp = NULL;
623: return;
624: }
625:
626: switch (coffsym.n_sclass) {
627: case C_EXT:
628: case C_EXTDEF:
629: break;
630: default:
631: continue;
632: }
633:
634: coff_to_lout(&coffsym, &lds, str_tabp, scnhp);
635:
636: sp->s_hash = hash(&lds);
637: sp->s_type = lds.ls_type;
638: sp->s_sval = lds.ls_addr;
639:
640: gblsymMap[sp-ssymp] = snsym - n - 1;
641: sp++;
642: }
643: gblsymMap=(off_t *)realloc( gblsymMap, (sp-ssymp)*sizeof(off_t) );
644: ssymp=(SYM *)realloc( ssymp, (sp-ssymp)*sizeof(SYM) );
645: sngblsym = sp - ssymp;
646: if (str_tabp) nfree(str_tabp);
647: nfree(scnhp);
648: }
649:
650: char *
651: read_str_tab(fp, nsyms, symptr)
652: FILE *fp;
653: long nsyms;
654: long symptr;
655: {
656: long strtab_len, symtab_len;
657: unsigned len;
658: char * strTabp;
659:
660: strtab_len = 0;
661: strTabp = NULL;
662: len = symtab_len = sizeof(SYMENT) * nsyms;
663: if (!len)
664: return(NULL);
665:
666: if (symtab_len != len) {
667: panic("Cannot process small model");
668: }
669: fseek(fp, symptr+len, 0);
670: if (1 != fread(&strtab_len, sizeof(strtab_len), 1, fp)) {
671: strtab_len = 0;
672: }
673: if (!strtab_len)
674: return(NULL);
675:
676: len = strtab_len -= 4;
677: if (len != strtab_len)
678: panic("Cannot process small model");
679: if ( (strTabp = nalloc((int)len)) == NULL ) {
680: printf("Not enough memory for the symbol string table.\n");
681: return(NULL);
682: }
683: if ( fread(strTabp, len, 1, fp) != 1) {
684: printf("Unable to read symbol string table.\n");
685: return(NULL);
686: }
687:
688: return(strTabp);
689: }
690:
691: SCNHDR *
692: read_scns(fp, nscns, scnh_off)
693: FILE *fp;
694: unsigned short nscns, scnh_off;
695: {
696: int len;
697: SCNHDR *scnhp;
698:
699: len = (int)(nscns*sizeof(SCNHDR));
700: if ( (scnhp = nalloc(len)) == NULL ) {
701: printf("Not enough memory for the symbol string table.\n");
702: return(NULL);
703: }
704: fseek(fp, scnh_off, 0);
705: if ( fread(scnhp, len, 1, fp) != 1) {
706: printf("Unable to read section headers.\n");
707: return(NULL);
708: }
709: return(scnhp);
710: }
711:
712: coff_to_lout(coffsymp, ldsp, str_tabp, scnhp)
713: SYMENT *coffsymp;
714: struct LDSYM *ldsp;
715: char *str_tabp;
716: SCNHDR *scnhp;
717: {
718: char *cp;
719: char w1[SYMNMLEN+1];
720:
721: cp = symName(coffsymp, w1, str_tabp);
722: memcpy(ldsp->ls_id, cp, NCPLN-1);
723: ldsp->ls_id[NCPLN-1] = '\0';
724:
725: switch((int)scnhp[coffsymp->n_scnum-1].s_flags) {
726: case STYP_TEXT:
727: ldsp->ls_type = L_GLOBAL + L_SHRI;
728: break;
729: case STYP_DATA:
730: ldsp->ls_type = L_GLOBAL + L_PRVD;
731: break;
732: case STYP_BSS:
733: ldsp->ls_type = L_GLOBAL + L_BSSD;
734: break;
735: default:
736: ldsp->ls_type = -1;
737: panic("Unallowed section flag in coff header");
738: }
739:
740: ldsp->ls_addr = (long)coffsymp->n_value;
741: }
742:
743: /*
744: * Symbol name.
745: */
746: static char *
747: symName(sym, work, str_tabp)
748: SYMENT *sym;
749: char *work;
750: char *str_tabp;
751: {
752: if (!sym->n_zeroes) {
753: return (str_tabp + sym->n_offset - 4);
754: }
755:
756: /* make sure it's zero terminated */
757: memcpy(work, sym->n_name, SYMNMLEN);
758: work[SYMNMLEN] = '\0';
759: return (work);
760: }
761:
762: /* end of trace1.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.