|
|
1.1 root 1: /*
2: * A debugger.
3: * Miscellaneous routines.
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:
15: /*
16: * Save the rest of the input line in `miscbuf'. If line is
17: * not given, save the default, `cp'.
18: */
19: getline(cp)
20: register char *cp;
21: {
22: register int c;
23: register char *bp;
24:
25: bp = miscbuf;
26: if ((c=getn()) != '\n') {
27: while (c != '\n') {
28: if (c == '\\')
29: if ((c=getn())!='\n' && c!='\\')
30: *bp++ = '\\';
31: *bp++ = c;
32: c = getn();
33: }
34: } else {
35: while (*cp != '\0')
36: *bp++ = *cp++;
37: }
38: *bp++ = '\n';
39: *bp = '\0';
40: }
41:
42: /*
43: * Add a string onto the input stream.
44: */
45: addstrp(cp)
46: char *cp;
47: {
48: register INP *ip;
49:
50: ip = nalloc(sizeof (INP));
51: ip->i_next = inpp;
52: ip->i_type = ICORE;
53: ip->i_strp = cp;
54: inpp = ip;
55: }
56:
57: /*
58: * Add a file pointer onto the input stack.
59: */
60: addfilp(fp)
61: FILE *fp;
62: {
63: register INP *ip;
64:
65: ip = nalloc(sizeof (INP));
66: ip->i_next = inpp;
67: ip->i_type = IFILE;
68: ip->i_filp = fp;
69: inpp = ip;
70: }
71:
72: /*
73: * Get the next character from the input stream.
74: */
75: getn()
76: {
77: register INP *ip;
78: register int c;
79:
80: if (lastc != '\0') {
81: c = lastc;
82: lastc = '\0';
83: return (c);
84: }
85: while ((ip=inpp) != NULL) {
86: switch (ip->i_type) {
87: case ICORE:
88: if ((c=*ip->i_strp++) != '\0')
89: return (c);
90: break;
91: case IFILE:
92: if ((c=getc(ip->i_filp)) != EOF)
93: return (c);
94: if (ip->i_filp == stdin) {
95: if (testint())
96: continue;
97: leave();
98: }
99: fclose(ip->i_filp);
100: break;
101: }
102: inpp = inpp->i_next;
103: nfree(ip);
104: }
105: return (EOF);
106: }
107:
108: /*
109: * Put back a character onto the current input stream.
110: */
111: ungetn(c)
112: {
113: lastc = c;
114: }
115:
116: /*
117: * Put out an address. `t' is the tolerance allowed.
118: */
119: putaddr(s, l, t)
120: long l;
121: {
122: register char *sp;
123:
124: sp = conaddr(miscbuf, s, l, t);
125: *sp = '\0';
126: printx("%s", miscbuf);
127: }
128:
129: /*
130: * Read `n' bytes from the current position in segment `seg'
131: * and store it in the buffer `bp'.
132: */
133: getb(segn, bp, n)
134: char *bp;
135: unsigned n;
136: {
137: if (getputb(segn, bp, n, 0) == 0)
138: return (0);
139: canon(bp, n);
140: return (1);
141: }
142:
143: /*
144: * Put `n' bytes from the buffer `bp' into segment `seg'.
145: */
146: putb(segn, bp, n)
147: char *bp;
148: unsigned n;
149: {
150: canon(bp, n);
151: return (getputb(segn, bp, n, 1));
152: }
153:
154: /*
155: * Canonize the buffer `bp' of length `n' according to `cantype'.
156: */
157: canon(bp, n)
158: register char *bp;
159: unsigned n;
160: {
161: register int i;
162: register int t;
163:
164: if (cantype == 1) {
165: if ((n&1) != 0)
166: return;
167: for (i=0; i<n; i+=2) {
168: t = bp[i];
169: bp[i] = bp[i+1];
170: bp[i+1] = t;
171: }
172: }
173: }
174:
175: /*
176: * Move `n' bytes between the buffer `bp' and the segment `segn'.
177: * The flag `d' controls the direction.
178: */
179: getputb(segn, bp, n, d)
180: char *bp;
181: unsigned n;
182: {
183: register MAP *mp;
184: register unsigned l;
185: register unsigned s;
186: register int (*f)();
187: fsize_t a;
188:
189: s = n;
190: a = add;
191: while (s) {
192: if ((mp=mapaddr(segn, a)) == NULL)
193: return (0);
194: l = s;
195: if (a+l > mp->m_bend)
196: l = mp->m_bend-a+1;
197: f = d ? mp->m_putf : mp->m_getf;
198: if( (*f)( mp->m_segi, mp->m_offt+
199: ( fflag ? a - mp->m_base : size( a - mp->m_base))
200: , bp, l) == 0)
201: return (0);
202: bp += l;
203: a += l;
204: s -= l;
205: }
206: add += n;
207: return (1);
208: }
209:
210: /*
211: * Given a segment number and an address, return the segment map
212: * in which the address falls.
213: */
214: MAP *
215: mapaddr(n, a)
216: fsize_t a;
217: {
218: register MAP *mp;
219:
220: for (mp=segmapl[n]; mp != NULL; mp=mp->m_next)
221: if (mp->m_base<=a && a<mp->m_bend)
222: break;
223: return (mp);
224: }
225:
226: /*
227: * Read a symbol and return it's value in the given `VAL' structure.
228: */
229: getsval(vp)
230: VAL *vp;
231: {
232: register int n;
233: register int c;
234: struct ldsym lds;
235:
236: n = 0;
237: c = getn();
238: while (isascii(c) && (isalnum(c)||c=='_')) {
239: if (n < NCPLN)
240: lds.ls_id[n++] = c;
241: c = getn();
242: }
243: ungetn(c);
244: while (n < NCPLN)
245: lds.ls_id[n++] = '\0';
246: if (specsym(&lds)==0 && regaddr(&lds)==0 && nameval(&lds)==0) {
247: printe("Symbol not found");
248: return (0);
249: }
250: switch (lds.ls_type&LR_SEG) {
251: case L_SHRI:
252: case L_PRVI:
253: case L_BSSI:
254: vp->v_segn = 1;
255: vp->v_flag = VLVAL;
256: break;
257: case L_SHRD:
258: case L_PRVD:
259: case L_BSSD:
260: case L_ABS:
261: vp->v_segn = 0;
262: vp->v_flag = VLVAL;
263: break;
264:
265: case L_REF:
266: printe("Symbol not defined");
267: return (0);
268: case L_REG:
269: vp->v_segn = 2;
270: vp->v_flag = VLVAL;
271: break;
272: }
273: vp->v_nval = lds.ls_addr;
274: return (1);
275: }
276:
277: /*
278: * See if the given symbol is a special symbol.
279: */
280: specsym(ldp)
281: register struct ldsym *ldp;
282: {
283: if (ldp->ls_id[1] != '\0')
284: return (0);
285: switch (ldp->ls_id[0]) {
286: case 'd':
287: ldp->ls_type = L_SHRD;
288: break;
289: case 'i':
290: ldp->ls_type = L_SHRI;
291: break;
292: case 'u':
293: ldp->ls_type = L_REG;
294: break;
295: default:
296: return (0);
297: }
298: ldp->ls_addr = 0;
299: return (1);
300: }
301:
302: /*
303: * Convert a value to an address. `t' is the tolerance
304: * allowed.
305: */
306: char *
307: conaddr(sp, s, l, t)
308: register char *sp;
309: unsigned long l;
310: {
311: /* Bug in PDP11 compiler
312: register unsigned d;
313: */
314: unsigned d;
315: struct ldsym ldsym;
316:
317: /* Bug in 8086 compiler
318: if (t<0 || valname(s, (tvaddr)l, &ldsym)==0 || (d=l-ldsym.ls_addr)>t)
319: */
320: if (t<0 || valname(s, (tvaddr)l, &ldsym)==0 ||
321: (d=(unsigned)l-ldsym.ls_addr)>t)
322: #if FORZ8001
323: conaddnum( sp, l);
324: #else
325: concons(sp, l);
326: #endif
327: else {
328: sprintf(sp, "%.*s", NCPLN, ldsym.ls_id);
329: while (*sp)
330: sp++;
331: if (d != 0) {
332: *sp++ = '+';
333: concons( sp, (long)d);
334: }
335: }
336: while (*sp)
337: sp++;
338: return (sp);
339: }
340:
341: /*
342: * Find the value of a symbol.
343: */
344: nameval(ldp)
345: struct ldsym *ldp;
346: {
347: register int u;
348: register fsize_t n;
349: register SYM *sp;
350: register int r;
351: register int h;
352: register fsize_t b;
353: struct ldsym lds;
354: struct ldsym ldu;
355:
356: u = 0;
357: h = hash(ldp);
358: for (n=snsym, sp=ssymp, b=sbase; n--; sp++, b+=sizeof(lds)) {
359: if (ssymp!=NULL && sp->s_hash!=h)
360: continue;
361: fseek(sfp, (long)b, 0);
362: if (fread(&lds, sizeof(lds), 1, sfp) != 1)
363: return (0);
364: #if NOUT
365: canshort( lds.ls_type);
366: canlong( lds.ls_addr);
367: #else
368: canint(lds.ls_type);
369: canvaddr(lds.ls_addr);
370: #endif
371: if ((r=namecmp(ldp, &lds)) > 0) {
372: *ldp = lds;
373: return (1);
374: }
375: if (r < 0) {
376: ldu = lds;
377: u = 1;
378: }
379: }
380: if (u) {
381: *ldp = ldu;
382: return (1);
383: }
384: return (0);
385: }
386:
387: /*
388: * Compare the names of two symbol table entries. If the compare
389: * fails and the name of the first entry doesn't already end with
390: * an '_', the compare is effectively tried again after appending
391: * an '_', to the end of the first symbol name.
392: */
393: namecmp(ldp1, ldp2)
394: struct ldsym *ldp1;
395: struct ldsym *ldp2;
396: {
397: register char *cp1;
398: register char *cp2;
399: register int n;
400:
401: n = CCSSIZE;
402: cp1 = ldp1->ls_id;
403: cp2 = ldp2->ls_id;
404: do {
405: if (*cp1 != *cp2++) {
406: if (*cp2!='\0' || *--cp2!='_')
407: return (0);
408: if (*cp1!='\0' || *--cp1=='_')
409: return (0);
410: return (-1);
411: }
412: if (*cp1++ == '\0')
413: return (1);
414: } while (--n);
415: return (1);
416: }
417:
418: /*
419: * Given a value, find the closest symbol below.
420: * Searches in segment s; if s = -1 looks in all segments.
421: */
422: valname(s, m, ldp)
423: tvaddr m;
424: struct ldsym *ldp;
425: {
426: register int n;
427: register tvaddr a;
428: register SYM *sp;
429: register int t;
430: register int n1;
431: register tvaddr a1;
432: struct ldsym lds;
433:
434: strncpy(ldp->ls_id, "", NCPLN);
435: if (sfp == NULL)
436: return (0);
437: a1 = 0;
438: n1 = -1;
439: if (ssymp == NULL)
440: fseek(sfp, (long)sbase, 0);
441: for (n=0, sp=ssymp; n<snsym; n++, sp++) {
442: if (ssymp != NULL) {
443: a = sp->s_sval;
444: t = sp->s_type;
445: } else {
446: if (fread(&lds, sizeof(lds), 1, sfp) != 1)
447: return (0);
448: #if NOUT
449: canshort( lds.ls_type);
450: canlong( lds.ls_addr);
451: #else
452: canint(lds.ls_type);
453: canvaddr(lds.ls_addr);
454: #endif
455: a = lds.ls_addr;
456: t = lds.ls_type;
457: }
458: switch (t&LR_SEG) {
459: case L_SHRI:
460: case L_PRVI:
461: case L_BSSI:
462: if (s == 0)
463: continue;
464: break;
465: case L_SHRD:
466: case L_PRVD:
467: case L_BSSD:
468: if (s == 1)
469: continue;
470: break;
471: default:
472: continue;
473: }
474: if (a <= m) {
475: if (a1==0 || a>a1) {
476: a1 = a;
477: n1 = n;
478: }
479: }
480: }
481: if (n1 >= 0) {
482: fseek(sfp, (long)sbase + n1*sizeof(struct ldsym), 0);
483: if (fread(ldp, sizeof(*ldp), 1, sfp) != 1)
484: return (0);
485: #if NOUT
486: canshort( lds.ls_type);
487: canlong( lds.ls_addr);
488: #else
489: canint(ldp->ls_type);
490: canvaddr(ldp->ls_addr);
491: #endif
492: return (1);
493: }
494: return (0);
495: }
496:
497: /*
498: * Read `n' bytes from the file specified by `f' starting at
499: * address `seek'.
500: */
501: getf(f, seek, bp, n)
502: long seek;
503: char *bp;
504: {
505: register FILE *fp;
506:
507: fp = f ? cfp : lfp;
508: fseek(fp, (long)seek, 0);
509: return (fread(bp, n, 1, fp));
510: }
511:
512: /*
513: * Write `n' bytes into the files specified by `f' starting at
514: * address `seek'.
515: */
516: putf(f, seek, bp, n)
517: long seek;
518: char *bp;
519: {
520: register FILE *fp;
521:
522: fp = f ? cfp : lfp;
523: fseek(fp, (long)seek, 0);
524: return (fwrite(bp, n, 1, fp) && fflush(fp)!=EOF);
525: }
526:
527: /*
528: * Allocate `n' bytes.
529: */
530: char *
531: nalloc(n)
532: {
533: register char *cp;
534:
535: if ((cp=malloc(n)) == NULL)
536: panic("No memory");
537: return (cp);
538: }
539:
540: /*
541: * Print out an error message and exit.
542: */
543: panic(a1)
544: char *a1;
545: {
546: fprintf(stderr, "%r", &a1);
547: putc('\n', stderr);
548: exit(1);
549: }
550:
551: /*
552: * Print out a breakpoint error message.
553: */
554: printb(a)
555: vaddr_t a;
556: {
557: fprintf(stderr, "Breakpoint error at ");
558: fprintf(stderr, DAFMT, (long)a);
559: putc('\n', stderr);
560: }
561:
562: /*
563: * Print out a fatal error message.
564: */
565: printr(a1)
566: char *a1;
567: {
568: fprintf(stderr, "%r", &a1);
569: putc('\n', stderr);
570: }
571:
572: /*
573: * Print out an error message.
574: */
575: printe(sp)
576: char *sp;
577: {
578: errrstr = sp;
579: fprintf(stderr, "?\n");
580: }
581:
582: /*
583: * Print formatted.
584: */
585: printx(a1)
586: char *a1;
587: {
588: printf("%r", &a1);
589: }
590:
591: putaddnum( a)
592: long a;
593: {
594: char buf[40];
595:
596: conaddnum( buf, a);
597: printx( "%s", buf);
598: }
599:
600: putnum( a)
601: long( a);
602: {
603: char buf[20];
604:
605: concons( buf, a);
606: printx( "%s", buf);
607: }
608:
609: char *
610: concons( sp, a)
611: char *sp;
612: long a;
613: {
614: register char *cp = sp;
615:
616: switch( dbase) {
617: case 8: sprintf( cp, "%lo", a); break;
618: case 10: sprintf( cp, "%ld", a); break;
619: case 16: sprintf( cp, "%lx", a); break;
620: }
621: while( *++cp) ;
622: return( cp);
623: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.