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