|
|
1.1 root 1: /*
2: * A debugger.
3: * Initialisation, command line parsing.
4: */
5: #include <stdio.h>
6: #include <ctype.h>
7: #include <canon.h>
8: #include "trace.h"
9: #if NOUT
10: #include <n.out.h>
11: #else
12: #include <l.out.h>
13: #endif
14: #include <sys/proc.h>
15: #include <signal.h>
16: #include <sys/uproc.h>
17:
18: main(argc, argv)
19: char **argv;
20: {
21: initialise();
22: setup(argc, argv);
23: signal(SIGINT, &armsint);
24: signal(SIGQUIT, SIG_IGN);
25: process();
26: }
27:
28: /*
29: * Leave.
30: */
31: leave()
32: {
33: killc();
34: exit(0);
35: }
36:
37: /*
38: * Initialise.
39: */
40: initialise()
41: {
42: register int i;
43:
44: for (i=0; i<NSEGM; i++)
45: strcpy(&segform[i][0], "aw");
46: strcpy(&segform[1][0], "ai");
47: bptinit();
48: }
49:
50: /*
51: * Setup arguments.
52: */
53: setup(argc, argv)
54: char **argv;
55: {
56: register char *cp;
57: register int c;
58: register int t;
59: register int u;
60: register int tflag;
61:
62: t = '\0';
63: tflag = 0;
64: for (; argc>1; argc--, argv++) {
65: cp = argv[1];
66: if (*cp++ != '-')
67: break;
68: while ((c=*cp++) != '\0') {
69: switch (c) {
70: case 'c':
71: case 'd':
72: case 'e':
73: case 'f':
74: case 'k':
75: case 'o':
76: if (t != '\0')
77: usage();
78: t = c;
79: continue;
80: case 'h':
81: hflag = 1;
82: continue;
83: case 'r':
84: rflag = 1;
85: continue;
86: case 's':
87: sflag = 1;
88: continue;
89: case 't':
90: tflag = 1;
91: continue;
92: default:
93: usage();
94: }
95: }
96: }
97: switch (t) {
98: case '\0':
99: switch (argc) {
100: case 1:
101: setlout("l.out", 3);
102: setcore("core");
103: break;
104: case 2:
105: setlout(argv[1], 3);
106: break;
107: case 3:
108: setlout(argv[1], 3);
109: setcore(argv[2]);
110: break;
111: default:
112: usage();
113: }
114: break;
115: case 'c':
116: switch (argc) {
117: case 1:
118: setlout("l.out", 3);
119: setcore("core");
120: break;
121: case 2:
122: setcore(argv[1]);
123: break;
124: case 3:
125: setlout(argv[1], 3);
126: setcore(argv[2]);
127: break;
128: default:
129: usage();
130: }
131: break;
132: case 'd':
133: switch (argc) {
134: case 1:
135: setlout("/coherent", 3);
136: setdump("/dev/dump");
137: break;
138: case 3:
139: setlout(argv[1], 3);
140: setdump(argv[2]);
141: break;
142: default:
143: usage();
144: }
145: break;
146: case 'e':
147: if (argc < 2)
148: usage();
149: setlout(argv[1], 3);
150: if (startup(&argv[1], NULL, NULL, 0)==0 || shiftup()==0)
151: leave();
152: break;
153: case 'f':
154: fflag = 1;
155: switch (argc) {
156: case 2:
157: setfile(argv[1]);
158: break;
159: case 3:
160: setlout(argv[1], 1);
161: setfile(argv[2]);
162: break;
163: default:
164: usage();
165: }
166: break;
167: case 'k':
168: switch (argc) {
169: case 1:
170: setlout("/coherent", 1);
171: setkmem("/dev/mem");
172: break;
173: case 2:
174: setkmem(argv[1]);
175: break;
176: case 3:
177: setlout(argv[1], 1);
178: setkmem(argv[2]);
179: break;
180: default:
181: usage();
182: }
183: break;
184: case 'o':
185: switch (argc) {
186: case 1:
187: setlout("l.out", 3);
188: break;
189: case 2:
190: setlout(argv[1], 3);
191: break;
192: case 3:
193: setlout(argv[1], 1);
194: setlout(argv[2], 2);
195: break;
196: default:
197: usage();
198: }
199: }
200: if (tflag) {
201: if ((u=open("/dev/tty", 2)) < 0)
202: panic("Cannot open /dev/tty");
203: dup2(u, 0);
204: dup2(u, 1);
205: dup2(u, 2);
206: }
207: }
208:
209: /*
210: * Generate a usage message.
211: */
212: usage()
213: {
214: panic("Usage: db [-cdefort] [object file] [auxiliary file]");
215: }
216:
217: /*
218: * Catch and flag interrupts.
219: */
220: armsint()
221: {
222: signal(SIGINT, &armsint);
223: intflag++;
224: }
225:
226: /*
227: * Check for interrupts and clear flag.
228: */
229: testint()
230: {
231: register int n;
232:
233: if ((n=intflag) != 0)
234: printe("Interrupt");
235: intflag = 0;
236: return (n);
237: }
238:
239: /*
240: * Assume the file, `np', is the name of an l.out. If the bottom bit
241: * of the flag is set, set up the symbol table. If the next bit is set,
242: * set up segmentation for the l.out.
243: */
244: setlout(np, f)
245: char *np;
246: {
247: struct ldheader ldh;
248:
249: lfp = openfil(np, (f&2) ? rflag : 1);
250: if (fread(&ldh, sizeof(ldh), 1, lfp) != 1)
251: panic("Cannot read object file");
252: canlout(&ldh);
253: if (ldh.l_magic != L_MAGIC)
254: panic("Bad object file");
255: objflag = 1;
256: if ((f&1) != 0) {
257: #if NOUT
258: sbase = ldh.l_tbase;
259: #else
260: sbase = sizeof(ldh);
261: #endif
262: sbase += ldh.l_ssize[L_SHRI] + ldh.l_ssize[L_PRVI];
263: sbase += ldh.l_ssize[L_SHRD] + ldh.l_ssize[L_PRVD];
264: snsym = ldh.l_ssize[L_SYM] / sizeof(struct ldsym);
265: if (snsym != 0) {
266: sfp = lfp;
267: if (sflag == 0)
268: readsym(sfp);
269: }
270: }
271: if ((f&2) != 0) {
272: lfn = np;
273: setaseg(&ldh);
274: }
275: }
276:
277: /*
278: * Canonize an l.out header.
279: */
280: canlout(ldp)
281: struct ldheader *ldp;
282: {
283: register int i;
284:
285: #if NOUT
286: canshort( ldp->l_magic);
287: canshort( ldp->l_flag);
288: canshort( ldp->l_machine);
289: canshort( ldp->l_tbase);
290: canlong( ldp->l_entry);
291: #else
292: canint( ldp->l_magic);
293: canint( ldp->l_flag);
294: canint( ldp->l_machine);
295: canvaddr( ldp->l_entry);
296: #endif
297: for (i=0; i<NLSEG; i++)
298: #if NOUT
299: canlong( ldp->l_ssize[i]);
300: #else
301: cansize( ldp->l_ssize[i]);
302: #endif
303: }
304:
305: /*
306: * Read all global symbols into memory.
307: */
308: readsym(fp)
309: FILE *fp;
310: {
311: register int n;
312: register SYM *sp;
313: struct ldsym lds;
314:
315: if ((ssymp=nalloc((int)snsym * sizeof(SYM))) == NULL)
316: return;
317: fseek(fp, (long)sbase, 0);
318: for (n=snsym, sp=ssymp; n--; sp++) {
319: if (fread(&lds, sizeof(lds), 1, fp) != 1) {
320: nfree(ssymp);
321: ssymp = NULL;
322: return;
323: }
324: #if NOUT
325: canshort( lds.ls_type);
326: canlong( lds.ls_addr);
327: #else
328: canint( lds.ls_type);
329: canvaddr( lds.ls_addr);
330: #endif
331: sp->s_hash = hash(&lds);
332: sp->s_type = lds.ls_type;
333: sp->s_sval = lds.ls_addr;
334: }
335: }
336:
337: /*
338: * Hash a symbol name.
339: */
340: hash(ldp)
341: struct ldsym *ldp;
342: {
343: register int h, n;
344: register char *cp;
345:
346: h = 0;
347: n = CCSSIZE;
348: cp = ldp->ls_id;
349: do {
350: if (*cp != '_')
351: h += *cp;
352: if (*cp++ == '\0')
353: break;
354: } while (--n);
355: return (h&0377);
356: }
357:
358: /*
359: * Set up segmentation for a core dump. The registers are also read.
360: */
361:
362: MAP *
363: smapc( next, start, length, foffs)
364: MAP *next;
365: register tvaddr start;
366: fsize_t length, foffs;
367: {
368: return( setsmap( next, start, addr( size( start) + length) - start,
369: foffs, getf, putf, 1));
370: }
371: setcore(np)
372: char *np;
373: {
374: register unsigned i;
375: register MAP *mp;
376: register char *cp;
377: register char *lcp;
378: register fsize_t siz;
379: register fsize_t offt;
380: char ucomm[10];
381: SR usegs[NUSEG];
382:
383: cfp = openfil(np, rflag);
384: fseek(cfp, (long)offset(uproc, u_comm[0]), 0);
385: if ((cp=lfn)!=NULL && fread(ucomm, sizeof(ucomm), 1, cfp)==1) {
386: lcp = cp;
387: while (*cp) {
388: if (*cp++ == '/')
389: lcp = cp;
390: }
391: if (strncmp(lcp, ucomm, sizeof(ucomm)) != 0)
392: printr("Core different from object");
393: }
394: fseek(cfp, (long)offset(uproc, u_segl[0]), 0);
395: if (fread(usegs, sizeof(usegs), 1, cfp) != 1)
396: panic("Bad core file");
397: USPACE = setsmap(NULL, (fsize_t)0, (fsize_t)UPASIZE, (fsize_t)0,
398: getf, putf, 1);
399: mp = clrsmap(DSPACE, endpure);
400: offt = usegs[0].sr_size;
401: for (i=1; i<NUSEG; i++) {
402: if (usegs[i].sr_segp == NULL)
403: continue;
404: if ((~usegs[i].sr_flag) & (SRFDUMP|SRFPMAP))
405: continue;
406: siz = usegs[i].sr_size;
407: mp = smapc(mp, usegs[i].sr_base, siz, offt);
408: offt += siz;
409: }
410: if (ISPACE == DSPACE)
411: ISPACE = mp;
412: DSPACE = mp;
413: settrap();
414: setregs();
415: }
416:
417: /*
418: * Find out fault type.
419: */
420: settrap()
421: {
422: int f;
423:
424: trapstr = "???";
425: #if PDP11
426: add = 0724; /* old pdp11 cohos differs from src */
427: #else
428: add = offset(uproc, u_signo);
429: #endif
430: if (getb(2, (char *)&f, sizeof(f)) == 0) {
431: printr("Cannot read fault type");
432: return (0);
433: }
434: if (f<=0 || f>NSIG) {
435: printr("Bad fault type");
436: return (0);
437: }
438: trapstr = signame[f-1];
439: return (f);
440: }
441:
442: /*
443: * Set up segmentation for an ordinary file.
444: * This is really easy.
445: */
446: setfile(np)
447: char *np;
448: {
449: lfp = openfil(np, rflag);
450: DSPACE = setsmap(NULL, (fsize_t)0, (fsize_t)LI, (fsize_t)0,
451: getf, putf, 0);
452: ISPACE = DSPACE;
453: }
454:
455: /*
456: * Open the given file. If `rflag' is set, the file is opened for
457: * read only.
458: */
459: FILE *
460: openfil(np, rflag)
461: char *np;
462: {
463: register FILE *fp;
464:
465: if (rflag) {
466: if ((fp=fopen(np, "r")) != NULL)
467: return (fp);
468: } else {
469: if ((fp=fopen(np, "r+w")) != NULL)
470: return (fp);
471: if ((fp=fopen(np, "r")) != NULL) {
472: printr("%s: opened read only", np);
473: return (fp);
474: }
475: }
476: panic("Cannot open %s", np);
477: }
478:
479: /*
480: * Initialise an element of a segment map.
481: */
482: MAP *
483: setsmap(next, base, siz, offt, getf, putf, segi)
484: MAP *next;
485: fsize_t base;
486: fsize_t siz;
487: fsize_t offt;
488: int (*getf)();
489: int (*putf)();
490: {
491: register MAP *mp;
492:
493: mp = (MAP *)nalloc(sizeof(MAP));
494: mp->m_next = next;
495: mp->m_base = base;
496: mp->m_bend = base+siz;
497: mp->m_offt = offt;
498: mp->m_getf = getf;
499: mp->m_putf = putf;
500: mp->m_segi = segi;
501: return (mp);
502: }
503:
504: /*
505: * Clear a section of a segment map.
506: */
507: MAP *
508: clrsmap(mp, np)
509: register MAP *mp;
510: register MAP *np;
511: {
512: while (mp != np) {
513: nfree(mp);
514: mp = mp->m_next;
515: }
516: return (mp);
517: }
518:
519: /*
520: * Clear all maps.
521: */
522: clramap()
523: {
524: register int n;
525:
526: n = 0;
527: if (segmapl[0] == segmapl[1])
528: segmapl[n++] = NULL;
529: while (n < NSEGM) {
530: segmapl[n] = clrsmap(segmapl[n], NULL);
531: n++;
532: }
533: }
534:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.