|
|
1.1 root 1: /* Copyright (c) 1982 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)readobj.c 1.6 3/24/83";
4:
5: /*
6: * Read in the namelist from the obj file.
7: */
8:
9: #include "defs.h"
10: #include "sym.h"
11: #include "symtab.h"
12: #include "object.h"
13: #include "objfmt.h"
14: #include "main.h"
15: #include "mappings.h"
16: #include "mappings/filetab.h"
17: #include "mappings/linetab.h"
18: #include "objsym.rep"
19:
20: #define MAXSYMNO 6000
21:
22: char *objname = "obj";
23:
24: LOCAL SYM *sym[MAXSYMNO];
25:
26: readobj(file)
27: char *file;
28: {
29: register FILE *fp;
30: struct pxhdr hdr;
31:
32: if ((fp = fopen(file, "r")) == NIL) {
33: panic("can't open %s", file);
34: }
35: get(fp, hdr);
36: if (hdr.magicnum != MAGICNUM) {
37: fseek(fp, (long) (HEADER_BYTES - sizeof(struct pxhdr)), 0);
38: get(fp, hdr);
39: if (hdr.magicnum != MAGICNUM) {
40: fatal("%s is not a Pascal object file", file);
41: }
42: }
43: if (hdr.symtabsize == 0) {
44: fatal("%s doesn't have symbolic information", file);
45: }
46: objsize = hdr.objsize;
47: fseek(fp, (long) objsize, 1);
48: if (get(fp, nlhdr) != 1) {
49: panic("can't read nlhdr");
50: }
51: if (option('h')) {
52: printf("\nHeader information:\n");
53: printf("\tobject size %d\n", objsize);
54: printf("\tsymtab size %d\n", hdr.symtabsize);
55: printf("\tstringsize %d\n", nlhdr.stringsize);
56: printf("\tnsyms %d\n", nlhdr.nsyms);
57: printf("\tnfiles %d\n", nlhdr.nfiles);
58: printf("\tnlines %d\n", nlhdr.nlines);
59: }
60: stringtab = alloc(nlhdr.stringsize, char);
61: fread(stringtab, sizeof(char), nlhdr.stringsize, fp);
62: readsyms(fp);
63: readfiles(fp);
64: readlines(fp);
65: fclose(fp);
66: }
67:
68: /*
69: * Allocate and read in file name information table.
70: */
71:
72: LOCAL readfiles(fp)
73: register FILE *fp;
74: {
75: register int i;
76: register FILETAB *ftp;
77: FILETAB temp;
78: ADDRESS prevaddr;
79:
80: filetab = alloc(nlhdr.nfiles, FILETAB);
81: ftp = &filetab[0];
82: prevaddr = 0;
83: for (i = 0; i < nlhdr.nfiles; i++) {
84: fread(&temp, sizeof(FILETAB), 1, fp);
85: if (temp.addr != prevaddr) {
86: ftp++;
87: }
88: *ftp = temp;
89: ftp->filename += (int) stringtab;
90: prevaddr = ftp->addr;
91: }
92: nlhdr.nfiles = (ftp - &filetab[0]) + 1;
93: skimsource(filetab[0].filename);
94: dotpfile = filetab[0].filename;
95: }
96:
97: /*
98: * Allocate and read in line number information table.
99: */
100:
101: LOCAL readlines(fp)
102: FILE *fp;
103: {
104: register LINENO oline;
105: register ADDRESS oaddr;
106: register LINETAB *lp;
107: FILETAB *ftp;
108: OBJLINE info;
109:
110: if (nlhdr.nlines == 0) {
111: return;
112: }
113: linetab = alloc(nlhdr.nlines, LINETAB);
114: for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) {
115: lp->line = 0;
116: }
117: for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) {
118: if (ftp->lineindex < nlhdr.nlines) {
119: linetab[ftp->lineindex].line = ftp->line;
120: }
121: }
122: oline = 0;
123: oaddr = 0;
124: for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) {
125: if (lp->line != 0) {
126: oline = lp->line;
127: }
128: info.together = getw(fp);
129: oline += info.separate.lineincr;
130: oaddr += info.separate.addrincr;
131: lp->line = oline;
132: lp->addr = oaddr;
133: }
134: }
135:
136: /*
137: * Read in the symbols.
138: */
139:
140: readsyms(fp)
141: FILE *fp;
142: {
143: register int i;
144: int symno;
145:
146: symtab = st_creat(nlhdr.nsyms);
147: for (i = 0; i < nlhdr.nsyms; i++) {
148: symno = getw(fp);
149: if (symno >= MAXSYMNO) {
150: panic("symbol number too large (%d)", symno);
151: }
152: sym[symno] = readsym(fp);
153: }
154: if (backpatch() != 0) {
155: panic("patchlist not empty after reading namelist");
156: }
157: if (program == NIL) {
158: panic("no program");
159: }
160: maketypes();
161: }
162:
163: typedef struct patchinfo {
164: SYM **patchsym;
165: struct patchinfo *next_patch;
166: } PATCH;
167:
168: LOCAL PATCH *phead;
169:
170: /*
171: * Go through patchlist looking for symbol numbers for which the
172: * sym array now has a non-NIL entry.
173: *
174: * Afterwards, zap the sym array.
175: */
176:
177: int backpatch()
178: {
179: register PATCH *p, *last, *next;
180: register SYM *s, **t;
181: int count;
182:
183: last = NIL;
184: count = 0;
185: for (p = phead; p != NIL; p = next) {
186: next = p->next_patch;
187: t = p->patchsym;
188: if ((s = sym[(int) *t]) != NIL) {
189: *t = s;
190: if (last == NIL) {
191: phead = next;
192: } else {
193: last->next_patch = next;
194: }
195: dispose(p);
196: } else {
197: last = p;
198: count++;
199: }
200: }
201: for (t = &sym[0]; t < &sym[MAXSYMNO]; t++) {
202: *t = NIL;
203: }
204: return(count);
205: }
206:
207: /*
208: * Check to see if the given pointer (really symbol number) should
209: * be added to the patch list. The argument is double indirect
210: * to do call by reference passing.
211: */
212:
213: chkpatch(p)
214: SYM **p;
215: {
216: register SYM *s, *t;
217: register PATCH *patch;
218:
219: if ((s = *p) != NIL) {
220: if ((t = sym[(int) s]) != NIL) {
221: *p = t;
222: } else {
223: patch = alloc(1, PATCH);
224: patch->patchsym = p;
225: patch->next_patch = phead;
226: phead = patch;
227: }
228: }
229: }
230:
231: /*
232: * Free all the object information.
233: */
234:
235: objfree()
236: {
237: register int i;
238:
239: st_destroy(symtab);
240: dispose(stringtab);
241: dispose(filetab);
242: dispose(linetab);
243: clrfunctab();
244: for (i = 0; i < MAXSYMNO; i++) {
245: sym[i] = NIL;
246: }
247: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.