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