|
|
1.1 root 1: static char sccsid[] = "@(#)symt.c 4.1 10/9/80";
2: #include "head.h"
3: #include <a.out.h>
4: #include <stab.h>
5:
6: #ifndef STABTYPES
7: #define STABTYPES N_STAB
8: #endif
9: #include <sys/stat.h>
10:
11: struct user u;
12: int compar();
13: char *symfil;
14:
15: #ifdef FLEXNAMES
16:
17: struct nlist *symtab;
18: char nullname[] = {0,0,0,0,0,0,0,0,0}; /* a few 0 bytes */
19: off_t stoff;
20:
21: stread(buff, nbytes)
22: struct nlist *buff;
23: int nbytes;
24: {
25: register int from = stoff;
26:
27: stoff += nbytes;
28: if (stoff >= gstart)
29: return (-1);
30: if (nbytes < 0) {
31: from = stoff;
32: buff--;
33: }
34: from = (from - ststart);
35: *buff = symtab[from/sizeof (struct nlist)];
36: return (sizeof (struct nlist));
37: }
38:
39: stseek(off, rel)
40: long off;
41: {
42:
43: if (rel == 1)
44: stoff += off;
45: else
46: stoff = off;
47: }
48: #define bread(a,b,c) stread(b,c)
49: #define blseek(a,b,c) stseek(b,c)
50: #endif
51:
52: /* initialize file and procedure tables */
53: initfp() {
54: struct nlist stentry;
55: register struct proct *procp;
56: register struct filet *filep;
57: struct stat stbuf;
58:
59: long soffset;
60: int i, gflag = 0;
61: char class;
62: register char *p, *q;
63:
64: #ifdef FLEXNAMES
65: register struct nlist *sp;
66: int malformed = 0;
67: lseek(txtmap.ufd, gstart, 0);
68: if (read(txtmap.ufd, &ssiz, sizeof(ssiz)) != sizeof (ssiz)) {
69: printf("%s: no string table (old format?)\n", symfil);
70: exit(1);
71: }
72: strtab = (char *)malloc(ssiz);
73: if (strtab == 0) {
74: printf("no room for %d bytes of string table\n", ssiz);
75: exit(1);
76: }
77: ssiz -= sizeof (ssiz);
78: if (read(txtmap.ufd, strtab+sizeof (ssiz), ssiz) != ssiz) {
79: printf("%s: error reading string table\n", symfil);
80: exit(1);
81: }
82: i = gstart - ststart;
83: symtab = (struct nlist *)malloc(i);
84: if (symtab == 0) {
85: printf("no room for %d bytes of symbol table\n", i);
86: exit(1);
87: }
88: lseek(txtmap.ufd, ststart, 0);
89: if (read(txtmap.ufd, symtab, i) != i) {
90: printf("%s: error reading symbol table\n", symfil);
91: exit(1);
92: }
93: for (sp = &symtab[i/sizeof (struct nlist)]; --sp >= symtab; )
94: if (sp->n_un.n_strx != 0) {
95: if (sp->n_un.n_strx < sizeof (ssiz) || sp->n_un.n_strx >= ssiz) {
96: if (malformed == 0) {
97: printf("danger: mangled symbol table\n");
98: malformed = 1;
99: }
100: sp->n_un.n_name = nullname;
101: } else
102: sp->n_un.n_name = strtab + sp->n_un.n_strx;
103: } else
104: sp->n_un.n_name = nullname;
105: #endif
106: #ifndef VMUNIX
107: sbuf.fd = txtmap.ufd;
108: #endif
109: firstdata = MAXPOS;
110: soffset = ststart;
111: blseek(&sbuf,ststart,0);
112: filep = files = badfile = (struct filet *) sbrk(sizeof filep[0]);
113: procp = procs = badproc = (struct proct *) sbrk(sizeof procp[0]);
114:
115: for(;;) {
116: if (bread(&sbuf, &stentry, sizeof stentry) <
117: sizeof stentry) break;
118: class = stentry.n_type & STABMASK;
119: switch (class & STABMASK) {
120: case N_SO:
121: case N_SOL:
122: gflag++;
123: if (filep == badfile) {
124: p = sbrk(FILEINCR*sizeof filep[0]);
125: if (p < 0) {
126: perror("sdb");
127: exit(4);
128: }
129: q = p + FILEINCR*sizeof filep[0];
130: while (p > (char *) procs)
131: *--q = *--p;
132: badfile += FILEINCR;
133: procp = (struct proct *)
134: ((char *) procp +
135: FILEINCR*sizeof filep[0]);
136: procs = (struct proct *)
137: ((char *) procs +
138: FILEINCR*sizeof filep[0]);
139: badproc = (struct proct *)
140: ((char *)badproc +
141: FILEINCR*sizeof filep[0]);
142: }
143: filep->faddr = stentry.n_value;
144: filep->lineflag = (class == N_SOL);
145: filep->stf_offset = soffset;
146: #ifndef FLEXNAMES
147: p = filep->sfilename;
148: for (;;) {
149: for (i=0; i<8; i++) *p++ = stentry.n_un.n_name[i];
150: if (*(p-1) == '\0') break;
151: if (bread(&sbuf, &stentry, sizeof stentry)
152: < sizeof stentry)
153: error("Bad N_SO entry (1)");
154: if ((stentry.n_type & STABMASK) !=
155: (unsigned char) class)
156: error("Bad N_SO entry (2)");
157: soffset += sizeof stentry;
158: }
159: #else
160: filep->sfilename = stentry.n_un.n_name;
161: #endif
162: q = filep->sfilename;
163: for (p=fp; *q; *p++ = *q++) ;
164: *p = 0;
165: if (stat(filework, &stbuf) == -1)
166: printf("Warning: `%s' not found\n",
167: filep->sfilename);
168: else if (stbuf.st_mtime > symtime)
169: printf("Warning: `%s' newer than `%s'\n",
170: filep->sfilename,
171: symfil);
172: filep++;
173: break;
174:
175: case N_TEXT:
176: if (stentry.n_un.n_name[0] != '_') break;
177: case N_FUN:
178: case N_ENTRY:
179: if (procp == badproc) {
180: if (sbrk(PROCINCR*sizeof procp[0]) < 0) {
181: perror("sdb");
182: exit(4);
183: }
184: badproc += PROCINCR;
185: }
186: #ifndef FLEXNAMES
187: for(i=0; i<8; i++)
188: procp->pname[i] = stentry.n_un.n_name[i];
189: #else
190: procp->pname = stentry.n_un.n_name;
191: #endif
192: procp->paddr = stentry.n_value;
193: procp->st_offset = soffset;
194: procp->sfptr = (class != N_TEXT) ? filep - 1 : badfile;
195: procp->lineno = (class != N_TEXT) ? stentry.n_desc : 0;
196: procp->entrypt = (class & STABMASK) == N_ENTRY;
197: procp++;
198: break;
199: }
200: if (stentry.n_type & N_EXT) {
201: if (!extstart)
202: extstart = soffset;
203: if (stentry.n_type == N_DATA | N_EXT ||
204: stentry.n_type == N_BSS | N_EXT ||
205: stentry.n_value < firstdata)
206: firstdata = stentry.n_value;
207: }
208: soffset += sizeof stentry;
209: }
210: qsort(procs, procp-procs, sizeof procs[0], compar);
211: badproc->st_offset = badfile->stf_offset = soffset;
212: badproc->sfptr = procp->sfptr = badfile;
213: #ifndef FLEXNAMES
214: badproc->pname[0] = badfile->sfilename[0]=
215: procp->pname[0] = filep->sfilename[0] = '\0';
216: #else
217: badproc->pname = badfile->sfilename=
218: procp->pname = filep->sfilename = nullname;
219: #endif
220:
221: if (!gflag)
222: printf("Warning: `%s' not compiled with -g\n", symfil);
223: setcur(1);
224: }
225:
226: /* returns current procedure from state (curfile, fline) */
227: struct proct *
228: curproc() {
229: register ADDR addr;
230:
231: addr = getaddr("", fline);
232: if (addr == -1) return(badproc);
233: return(adrtoprocp(addr));
234:
235: }
236:
237: /* returns procedure s, uses curproc() if s == NULL */
238:
239: struct proct *
240: findproc(s)
241: char *s; {
242: register struct proct *p, *altproc;
243:
244: if (s[0] == '\0') return(curproc());
245: altproc = badproc;
246:
247: for (p=procs; p->pname[0]; p++) {
248: if (eqpat(s, p->pname)) return(p);
249: if (p->pname[0] == '_' && eqpatr(s, p->pname+1, 1))
250: altproc = p;
251: }
252: return(altproc);
253: }
254:
255: /* returns file s containing filename */
256: struct filet *
257: findfile(s)
258: char *s; {
259: register struct filet *f;
260: for (f=files; f->sfilename[0]; f++) {
261: if (eqpat(f->sfilename, s)) {
262: for( ; f->lineflag; f--) ;
263: if (f < files) error("Bad file array");
264: return(f);
265: }
266: }
267: return(f);
268: }
269:
270: /*
271: * slookup():
272: * looks up variable matching pat starting at (offset + sizeof stentry)
273: * in a.out, searching backwards,
274: * ignoring nested blocks to beginning to procedure.
275: * Returns its offset and symbol table entries decoded in sl_*
276: *
277: * If comblk == "*" then match both within and outside common blocks,
278: * if comblk == "" then match only outside common blocks,
279: * else match only within comblk.
280: */
281:
282: long
283: slookup(pat, poffset, stelt)
284: long poffset; char *pat; {
285: slookinit();
286: slooknext(pat, poffset, stelt, "*");
287: }
288:
289: int clevel, level, fnameflag, comfound, incomm;
290:
291: slookinit() {
292: clevel = level = fnameflag = comfound = incomm = 0;
293: }
294:
295: long
296: slooknext(pat, poffset, stelt, comblk)
297: long poffset; char *pat, *comblk; {
298: register int i;
299: register long offset;
300: char class, *q;
301: struct nlist stentry;
302: struct proct *procp, *p;
303:
304: offset = poffset + sizeof stentry;
305: if (debug) printf("slookup(%s,%d)\n",pat,offset);
306: blseek(&sbuf, offset, 0);
307:
308: for (;;) {
309: offset -= sizeof stentry;
310: if (offset < ststart) break;
311: if (bread(&sbuf, &stentry+1, -sizeof stentry)
312: < sizeof stentry) break;
313: class = stentry.n_type & STABMASK;
314: switch (class & STABMASK) {
315: case 0:
316: break;
317: case N_FUN:
318: return(-1);
319: case N_RBRAC:
320: level++;
321: break;
322: case N_LBRAC:
323: level--;
324: break;
325: case N_ECOMM:
326: #ifndef FLEXNAMES
327: for (q = &stentry.n_un.n_name[7]; q>=stentry.n_un.n_name; q--) {
328: if (*q == '_') {
329: *q = '\0';
330: break;
331: }
332: }
333: #else
334: for (q = stentry.n_un.n_name; *q; q++)
335: continue;
336: if (*--q == '_')
337: *q = 0;
338: #endif
339: if (eqpat(comblk, stentry.n_un.n_name))
340: comfound = 1;
341: incomm = 1;
342: case N_ECOML:
343: clevel++;
344: break;
345: case N_BCOMM:
346: comfound = incomm = 0;
347: clevel--;
348: break;
349: case N_FNAME:
350: if (fnameflag)
351: break;
352: procp = findproc(stentry.n_un.n_name);
353: for (p=procs; p->pname[0]; p++) {
354: if (p->entrypt == 0 &&
355: p->st_offset > procp->st_offset &&
356: p->st_offset < offset)
357: offset = p->st_offset;
358: }
359: clevel = level = 0;
360: fnameflag++;
361: blseek(&sbuf, offset, 0);
362: break;
363: default:
364: if (level <= 0 && eqpat(pat, stentry.n_un.n_name) &&
365: stentry.n_un.n_name[0] && class & STABTYPES &&
366: (eqstr("*", comblk) ||
367: (comblk[0] == '\0' && incomm == 0) ||
368: comfound) &&
369: (stelt == (class == N_SSYM))) {
370: if (class == N_LENG) {
371: sl_size = stentry.n_value;
372: offset -= sizeof stentry;
373: bread(&sbuf, &stentry+1,
374: -sizeof stentry);
375: if (stentry.n_type&~N_EXT == N_BSS) {
376: bread(&sbuf, &stentry+1,
377: -sizeof stentry);
378: offset -= sizeof stentry;
379: }
380: }
381: else sl_size = 0;
382: sl_class = stentry.n_type & STABMASK;
383: sl_type = stentry.n_desc;
384: sl_addr = stentry.n_value;
385: #ifndef FLEXNAMES
386: for (i=0; i<8; i++) sl_name[i] =
387: stentry.n_un.n_name[i];
388: #else
389: sl_name = stentry.n_un.n_name;
390: #endif
391: if (clevel != 0) docomm(offset);
392: return(offset - sizeof stentry);
393: }
394: }
395: }
396: return(-1);
397: }
398:
399: /*
400: * Look up global variable matching pat starting at (filestart+sizeof stentry)
401: * Return its offset and symbol table entries decoded in sl_*
402: */
403: long
404: globallookup(pat, filestart, stelt)
405: char *pat; long filestart; {
406: register int offset, i;
407: struct nlist stentry;
408: int class, clevel;
409:
410: if (debug) printf("globallookup(%s,%d)\n", pat,filestart);
411: blseek(&sbuf, filestart, 0);
412: offset = filestart - sizeof stentry;
413: clevel = 0;
414: do {
415: if (bread(&sbuf, &stentry, sizeof stentry) <
416: sizeof stentry) return(-1);
417: offset += sizeof stentry;
418: } while ((stentry.n_type & STABMASK) == N_SO);
419: for (;;) {
420: class = stentry.n_type & STABMASK;
421: switch (class & STABMASK) {
422: case N_SO:
423: return(-1);
424: case N_ECOMM:
425: clevel--;
426: break;
427: case N_BCOMM:
428: clevel++;
429: break;
430: default:
431: if (eqpat(pat, stentry.n_un.n_name)
432: && stentry.n_un.n_name[0] && class & STABTYPES) {
433: sl_class = stentry.n_type & STABMASK;
434: if (sl_class != N_GSYM && sl_class != N_SSYM &&
435: sl_class != N_STSYM && sl_class != N_LCSYM) goto g1;
436: if (stelt != (sl_class == N_SSYM)) goto g1;
437: sl_size = 0;
438: sl_type = stentry.n_desc;
439: sl_addr = stentry.n_value;
440: #ifndef FLEXNAMES
441: for (i=0; i<8; i++) sl_name[i] = stentry.n_un.n_name[i];
442: #else
443: sl_name = stentry.n_un.n_name;
444: #endif
445: if (clevel != 0) docomm(offset);
446: goto g2;
447: }
448: }
449: g1: if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry)
450: return(-1);
451: offset += sizeof stentry;
452: }
453: g2: bread(&sbuf, &stentry, sizeof stentry);
454: if (stentry.n_type&~N_EXT==N_BSS) {
455: bread(&sbuf, &stentry, sizeof stentry);
456: offset += sizeof stentry;
457: }
458: if (((stentry.n_type & STABMASK) == N_LENG) &&
459: (eqpat(sl_name, stentry.n_un.n_name)))
460: sl_size = stentry.n_value;
461:
462: if (sl_class == N_GSYM && (clevel == 0)) {
463: blseek(&sbuf, extstart, 0);
464: for(;;) {
465: if (bread(&sbuf, &stentry, sizeof stentry)
466: < sizeof stentry)
467: return(-1);
468: if (stentry.n_un.n_name[0] != '_') continue;
469: if (eqpatr(sl_name, stentry.n_un.n_name+1, 1)) {
470: sl_addr = stentry.n_value;
471: break;
472: }
473: }
474: }
475: return(offset + sizeof stentry);
476: }
477:
478: /* core address to procedure (pointer to proc array) */
479: struct proct *
480: adrtoprocp(addr)
481: ADDR addr; {
482: register struct proct *procp, *lastproc;
483: lastproc = badproc;
484: for (procp=procs; procp->pname[0]; procp++) {
485: if (procp->paddr > addr) break;
486: if (procp->entrypt == 0)
487: lastproc = procp;
488: }
489: return (lastproc);
490: }
491:
492:
493: /* core address to file (pointer to file array) */
494: struct filet *
495: adrtofilep(addr)
496: ADDR addr; {
497: register struct filet *filep;
498: for (filep=files; filep->sfilename[0]; filep++) {
499: if (filep->faddr > addr) break;
500: }
501: return (filep != files ? filep-1 : badfile);
502: }
503:
504: /*
505: * core address to linenumber
506: * Sets external exactaddr to addr if addr is NOT the first instruction
507: * of a line, set to -1 otherwise.
508: * Sets external lnfaddr to address of first statement in line.
509: */
510: long lastoffset;
511:
512: adrtolineno(addr)
513: ADDR addr; {
514: register int lineno;
515: long offset;
516: struct nlist stentry;
517:
518: exactaddr = addr;
519: lineno = lastoffset = -1;
520: offset = adrtoprocp(addr)->st_offset;
521: blseek(&sbuf, offset, 0);
522: for (;;) {
523: if (bread(&sbuf, &stentry, sizeof stentry)
524: < sizeof stentry) break;
525: if (stentry.n_type == N_SO)
526: break;
527: if (stentry.n_type == N_SLINE) {
528: if (stentry.n_value > addr)
529: break;
530: lastoffset = offset;
531: lineno = stentry.n_desc;
532: lnfaddr = stentry.n_value;
533: if (stentry.n_value == addr)
534: exactaddr = -1;
535: }
536: offset += sizeof stentry;
537: }
538: return (lineno);
539: }
540:
541:
542: /* address to a.out offset */
543: long
544: adrtostoffset(addr)
545: ADDR addr; {
546: adrtolineno(addr);
547: return(lastoffset);
548: }
549:
550:
551: /*
552: * Set (curfile, lineno) from core image.
553: * Returns 1 if there is a core image, 0 otherwise.
554: *
555: * Print the current line iff verbose is set.
556: */
557: setcur(verbose) {
558: register struct proct *procp;
559:
560: dot = *(ADDR *) (((ADDR) &u) + PC);
561:
562: if (dot == 0) {
563: printf("No core image\n");
564: goto setmain;
565: }
566: procp = adrtoprocp(dot);
567: if ((procp->sfptr) != badfile) {
568: finit(adrtofilep(procp->paddr)->sfilename);
569: ffind(adrtolineno(dot));
570: if (verbose) {
571: if (exactaddr != -1)
572: printf("0x%x in ", exactaddr);
573: #ifndef FLEXNAMES
574: printf("%.8s:", procp->pname);
575: #else
576: printf("%s:", procp->pname);
577: #endif
578: fprint();
579: }
580: return(1);
581: }
582: if (verbose) {
583: if (procp->pname[0] == '_')
584: #ifndef FLEXNAMES
585: printf("%.7s: address 0x%x\n", procp->pname+1, dot);
586: #else
587: printf("%s: address 0x%x\n", procp->pname+1, dot);
588: #endif
589: else
590: #ifndef FLEXNAMES
591: printf("%.8s: address %d\n", procp->pname, dot);
592: #else
593: printf("%s: address %d\n", procp->pname, dot);
594: #endif
595: }
596:
597: setmain:
598: procp = findproc("MAIN_");
599: if ((procp->pname[0] != 'M') || (procp->sfptr == badfile)) {
600: procp = findproc("main");
601: if ((procp->pname[0] != 'm') || (procp->sfptr == badfile)) {
602: /* printf("main not compiled with debug flag\n"); */
603: return(0);
604: }
605: }
606: finit(procp->sfptr->sfilename);
607: ffind(procp->lineno);
608: return(0);
609: }
610:
611: compar(a, b)
612: struct proct *a, *b; {
613: if (a->paddr == b->paddr) {
614: if (a->pname[0] == '_') return(-1);
615: if (b->pname[0] == '_') return(1);
616: return(0);
617: }
618: return(a->paddr < b->paddr ? -1 : 1);
619: }
620:
621: /* gets offset of file or procedure named s */
622: nametooffset(s)
623: char *s; {
624: register struct filet *f;
625: register struct proct *p;
626:
627: if (*s == '\0')
628: return(-1);
629: if (eqany('.', s)) {
630: f = findfile(s);
631: return(f->sfilename[0] ? f->stf_offset : -1);
632: }
633: p = findproc(s);
634: return(p->pname[0] ? p->st_offset : -1);
635: }
636:
637: /* returns s if its a filename, its file otherwise */
638: char *
639: nametofile(s)
640: char *s; {
641: register struct proct *p;
642:
643: if (eqany('.', s)) {
644: return(s);
645: }
646: p = findproc(s);
647: return(adrtofilep(p->paddr)->sfilename);
648: }
649:
650:
651: /* line number to address, starting at offset in a.out */
652: /* assumes that offset is within file */
653: lntoaddr(lineno, offset, file)
654: long offset; char *file; {
655: struct nlist stentry;
656: register int i, ignore = 0;
657: register int bestln=BIGNUM;
658: ADDR bestaddr;
659: char *p;
660:
661: blseek(&sbuf, offset, 0);
662:
663: do {
664: if (bread(&sbuf, &stentry, sizeof stentry) <
665: sizeof stentry) return(-1);
666: } while ((stentry.n_type & STABMASK) == N_SO);
667: for (;;) {
668: switch(stentry.n_type & STABMASK) {
669: case N_SLINE:
670: if (!ignore) {
671: if (stentry.n_desc == lineno)
672: return(stentry.n_value);
673: if (stentry.n_desc > lineno &&
674: stentry.n_desc < bestln) {
675: bestln = stentry.n_desc;
676: bestaddr = stentry.n_value;
677: }
678: }
679: break;
680:
681: case N_SO:
682: goto ret;
683:
684: case N_SOL:
685: p = file;
686: #ifndef FLEXNAMES
687: for (;;) {
688: for (i=0; i<8; i++) {
689: if (*p != stentry.n_un.n_name[i]) goto neq;
690: if (*p++ == '\0') break;
691: }
692: if (stentry.n_un.n_name[7] == '\0')
693: break;
694: if (bread(&sbuf, &stentry, sizeof stentry)
695: < sizeof stentry)
696: error("Bad N_SO entry (1)");
697: if ((stentry.n_type & STABMASK) !=
698: (unsigned char) N_SOL)
699: error("Bad N_SO entry (2)");
700: }
701: #else
702: if (strcmp(file, stentry.n_un.n_name))
703: goto neq;
704: #endif
705: ignore = 0;
706: break;
707:
708: neq: ignore++;
709: break;
710: }
711: if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry)
712: break;
713: }
714: ret: return(bestln == BIGNUM ? -1 : bestaddr);
715: }
716:
717: /* gets address of proc:number */
718: getaddr(proc,integ)
719: char *proc; {
720: register long offset;
721: register char *s, *f;
722: ADDR addr;
723:
724: s = proc[0] ? proc : curfile;
725: if (*s == '\0')
726: return(-1);
727: offset = nametooffset(s);
728: f = nametofile(s);
729: if (debug) printf("getaddr() computed offset %d", offset);
730: if (offset == -1) {
731: addr = extaddr(proc);
732: if (addr != -1) addr += 2; /* MACHINE DEPENDENT */
733: if (debug) printf(" extaddr computed %d\n", addr);
734: return(addr);
735: }
736: if (integ)
737: addr = lntoaddr(integ, offset, s);
738: else {
739: ADDR oldaddr;
740: oldaddr = findproc(proc)->paddr + 2; /* MACHINE DEPENDENT */
741: addr = lntoaddr(adrtolineno(addr)+1, offset, f);
742: if (addr == -1)
743: addr = oldaddr;
744: }
745: if (debug) printf(" and addr %d\n", addr);
746: if (addr == -1) return(-1);
747: return(addr);
748: }
749:
750: /* returns address of external */
751: ADDR
752: extaddr(name)
753: char *name; {
754: struct nlist stentry;
755: blseek(&sbuf, extstart, 0);
756:
757: for (;;) {
758: if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry)
759: return(-1);
760: if (stentry.n_un.n_name[0] == '_' &&
761: eqpatr(name, stentry.n_un.n_name+1, 1))
762: return(stentry.n_value);
763: }
764: }
765:
766:
767: /*
768: * Look up external data symbol matching pat starting at
769: * (filestart+sizeof stentry)
770: * Return its address in sl_addr and name in sl_name.
771: */
772: long
773: extlookup(pat, filestart)
774: char *pat; long filestart; {
775: register int offset, i;
776: struct nlist stentry;
777:
778: blseek(&sbuf, filestart, 0);
779: offset = filestart - sizeof stentry;
780: do {
781: if (bread(&sbuf, &stentry, sizeof stentry) <
782: sizeof stentry) return(-1);
783: offset += sizeof stentry;
784: } while ((stentry.n_type & STABMASK) == N_SO);
785: for (;;) {
786: if (stentry.n_un.n_name[0] == '_' &&
787: stentry.n_type == (N_DATA | N_EXT) &&
788: eqpatr(pat, stentry.n_un.n_name+1, 1)) {
789: sl_addr = stentry.n_value;
790: #ifndef FLEXNAMES
791: for (i=0; i<7; i++) sl_name[i] = stentry.n_un.n_name[i+1];
792: #else
793: sl_name = stentry.n_un.n_name;
794: #endif
795: return(offset + sizeof stentry);
796: }
797: g1: if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry)
798: return(-1);
799: offset += sizeof stentry;
800: }
801: }
802:
803: /* find enclosing common blocks and fix up addresses */
804: docomm(offset)
805: long offset; {
806: struct nlist stentry;
807:
808: for (;;) {
809: if (bread(&sbuf, &stentry, sizeof stentry) < sizeof stentry) {
810: error("Bad common block");
811: return;
812: }
813: sl_class = N_GSYM;
814: if ((stentry.n_type & STABMASK) == N_ECOMM) {
815: sl_addr += extaddr(stentry.n_un.n_name);
816: blseek(&sbuf, offset, 0);
817: return;
818: }
819: if ((stentry.n_type & STABMASK) == N_ECOML) {
820: sl_addr += stentry.n_value;
821: blseek(&sbuf, offset, 0);
822: return;
823: }
824: }
825: }
826:
827: /* determine if class is that of a variable */
828: char pctypes[] = {N_GSYM, N_STSYM, N_LCSYM, N_RSYM, N_SSYM, N_LSYM,
829: N_PSYM, 0};
830: varclass(class)
831: char class; {
832: char *p;
833:
834: for (p=pctypes; *p; p++) {
835: if (class == *p)
836: return(1);
837: }
838: return(0);
839: }
840:
841: /*
842: * address to external name
843: * returns difference between addr and address of external
844: * name returned in sl_name
845: */
846: adrtoext(addr)
847: ADDR addr; {
848: struct nlist stentry;
849: register int i, prevdiff = MAXPOS, diff;
850:
851: blseek(&sbuf, extstart, 0);
852: for (;;) {
853: if (bread(&sbuf, &stentry, sizeof stentry)
854: < sizeof stentry)
855: return (prevdiff!=MAXPOS ? prevdiff : -1);
856: if (stentry.n_type == (N_DATA | N_EXT) ||
857: stentry.n_type == (N_BSS | N_EXT)) {
858: diff = addr - stentry.n_value;
859: if (diff >= 0 && diff < prevdiff) {
860: #ifndef FLEXNAMES
861: for (i=0; i<7; i++)
862: sl_name[i] = stentry.n_un.n_name[i+1];
863: #else
864: sl_name = stentry.n_un.n_name;
865: #endif
866: if (diff == 0)
867: return(0);
868: prevdiff = diff;
869: }
870: }
871: }
872: }
873:
874: /*
875: * address to local name in procp
876: * returns difference between addr and address of local
877: * returned in sl_name
878: */
879: adrtolocal(addr, procp)
880: ADDR addr; struct proct *procp; {
881: struct nlist stentry;
882: register int i, prevdiff = MAXPOS, diff;
883:
884: blseek(&sbuf, procp->st_offset + sizeof stentry, 0);
885: for (;;) {
886: if (bread(&sbuf, &stentry, sizeof stentry)
887: < sizeof stentry)
888: return(prevdiff!=MAXPOS ? prevdiff : -1);
889: if (stentry.n_type == N_FUN)
890: return(prevdiff!=MAXPOS ? prevdiff : -1);
891: if (stentry.n_type == N_LSYM) {
892: diff = addr - stentry.n_value;
893: if (diff >= 0 && diff < prevdiff) {
894: #ifndef FLEXNAMES
895: for (i=0; i<8; i++)
896: sl_name[i] = stentry.n_un.n_name[i];
897: #else
898: sl_name = stentry.n_un.n_name;
899: #endif
900: if (diff == 0)
901: return(0);
902: prevdiff = diff;
903: }
904: }
905: }
906: }
907:
908: /*
909: * address to parameter name in procp
910: * returns difference between addr and address of local
911: * returned in sl_name
912: */
913: adrtoparam(addr, procp)
914: ADDR addr; struct proct *procp; {
915: struct nlist stentry;
916: register int i, prevdiff = MAXPOS, diff;
917:
918: blseek(&sbuf, procp->st_offset + sizeof stentry, 0);
919: for (;;) {
920: if (bread(&sbuf, &stentry, sizeof stentry)
921: < sizeof stentry)
922: return(prevdiff!=MAXPOS ? prevdiff : -1);
923: if (stentry.n_type == N_FUN)
924: return(prevdiff!=MAXPOS ? prevdiff : -1);
925: if (stentry.n_type == N_PSYM) {
926: diff = addr - stentry.n_value;
927: if (diff >= 0 && diff < prevdiff) {
928: #ifndef FLEXNAMES
929: for (i=0; i<8; i++)
930: sl_name[i] = stentry.n_un.n_name[i];
931: #else
932: sl_name = stentry.n_un.n_name;
933: #endif
934: if (diff == 0)
935: return(0);
936: prevdiff = diff;
937: }
938: }
939: }
940: }
941:
942: /*
943: * register number to register variable name in procp
944: * returned in sl_name
945: */
946: adrtoregvar(regno, procp)
947: ADDR regno; struct proct *procp; {
948: struct nlist stentry;
949: register int i;
950:
951: blseek(&sbuf, procp->st_offset + sizeof stentry, 0);
952: for (;;) {
953: if (bread(&sbuf, &stentry, sizeof stentry)
954: < sizeof stentry) return(-1);
955: if (stentry.n_type == N_FUN)
956: return(-1);
957: if (stentry.n_type == N_RSYM) {
958: if (stentry.n_value == regno) {
959: #ifndef FLEXNAMES
960: for (i=0; i<8; i++)
961: sl_name[i] = stentry.n_un.n_name[i];
962: #else
963: sl_name = stentry.n_un.n_name;
964: #endif
965: return(0);
966: }
967: }
968: }
969: }
970:
971: /* sets file map for M command */
972: setmap(s)
973: char *s; {
974: union {
975: MAP *m;
976: L_INT *mp;
977: } amap;
978: int starflag = 0;
979:
980: amap.mp = 0;
981: for (; *s; s++) {
982: switch (*s) {
983: case '/':
984: amap.m = &datmap;
985: break;
986: case '?':
987: amap.m = &txtmap;
988: break;
989: case '*':
990: starflag++;
991: break;
992: default:
993: goto sout;
994: }
995: }
996:
997: sout: if (amap.mp == 0) {
998: error("Map `?' or `/' must be specified");
999: return;
1000: }
1001: if (starflag)
1002: amap.mp += 3;
1003: for (; *s; s++) {
1004: if (*s >= '0' && *s <= '9')
1005: *(amap.mp)++ = readint(&s);
1006: }
1007: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.