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