1*5501Slinton /* Copyright (c) 1982 Regents of the University of California */
2*5501Slinton 
3*5501Slinton static char sccsid[] = "@(#)readsym.c 1.1 01/18/82";
4*5501Slinton 
5*5501Slinton /*
6*5501Slinton  * SYM representation dependent routines for reading in the
7*5501Slinton  * symbol information from the object file.
8*5501Slinton  */
9*5501Slinton 
10*5501Slinton #include "defs.h"
11*5501Slinton #include "sym.h"
12*5501Slinton #include "symtab.h"
13*5501Slinton #include "object.h"
14*5501Slinton #include "process.h"
15*5501Slinton #include "sym/classes.h"
16*5501Slinton #include "objsym.rep"
17*5501Slinton #include "sym/sym.rep"
18*5501Slinton 
19*5501Slinton LOCAL SYM *findblock();
20*5501Slinton LOCAL SYM *enterblock();
21*5501Slinton LOCAL SYM *findfunc();
22*5501Slinton 
23*5501Slinton /*
24*5501Slinton  * Read the information on a symbol from the object file, return a
25*5501Slinton  * SYM with the info.
26*5501Slinton  */
27*5501Slinton 
28*5501Slinton SYM *readsym(fp)
29*5501Slinton FILE *fp;
30*5501Slinton {
31*5501Slinton 	register SYM *s, *t;
32*5501Slinton 	SYM cursym;
33*5501Slinton 	static SYM *func;
34*5501Slinton 
35*5501Slinton 	t = &cursym;
36*5501Slinton 	getsym(fp, t);
37*5501Slinton 	if (isblock(t)) {
38*5501Slinton #		if (isvaxpx)
39*5501Slinton 			if (t->class == PROG) {
40*5501Slinton 				t->symvalue.funcv.codeloc = BASEADDR;
41*5501Slinton 			}
42*5501Slinton #		endif
43*5501Slinton 		s = findblock(t);
44*5501Slinton 		if (s->class == PROG) {
45*5501Slinton 			program = s;
46*5501Slinton 			s->func = NIL;
47*5501Slinton 		} else {
48*5501Slinton 			s->func = func;
49*5501Slinton 		}
50*5501Slinton 	} else if (t->class == BADUSE) {
51*5501Slinton 		func = enterblock(t);
52*5501Slinton 		return(func);
53*5501Slinton 	} else {
54*5501Slinton 		s = st_insert(symtab, t->symbol);
55*5501Slinton 		t->next_sym = s->next_sym;
56*5501Slinton 		*s = *t;
57*5501Slinton 		if (s->class == FVAR) {
58*5501Slinton 			s->func = findfunc(s);
59*5501Slinton 		} else {
60*5501Slinton 			s->func = func;
61*5501Slinton 		}
62*5501Slinton 	}
63*5501Slinton 
64*5501Slinton /*
65*5501Slinton  * This glitch is pi's fault.  It gives string constants
66*5501Slinton  * a type whose symbol number is -1.  For what reason, I know not.
67*5501Slinton  */
68*5501Slinton 	if (s->type == (SYM *) -1) {
69*5501Slinton 		s->type = NIL;
70*5501Slinton 	} else {
71*5501Slinton 		chkpatch(&s->type);
72*5501Slinton 	}
73*5501Slinton 	chkpatch(&s->chain);
74*5501Slinton 	if (s->class == RECORD || s->class == VARNT) {
75*5501Slinton 		chkpatch(&s->symvalue.varnt.vtorec);
76*5501Slinton 		chkpatch(&s->symvalue.varnt.vtag);
77*5501Slinton 	}
78*5501Slinton 	if (isblock(s)) {
79*5501Slinton 		fixparams(s);
80*5501Slinton 	}
81*5501Slinton 	return(s);
82*5501Slinton }
83*5501Slinton 
84*5501Slinton /*
85*5501Slinton  * Read the SYM information in the object file.
86*5501Slinton  */
87*5501Slinton 
88*5501Slinton LOCAL getsym(fp, t)
89*5501Slinton FILE *fp;
90*5501Slinton SYM *t;
91*5501Slinton {
92*5501Slinton 	OBJSYM osym;
93*5501Slinton 	register OBJSYM *o;
94*5501Slinton 
95*5501Slinton 	get(fp, osym);
96*5501Slinton 	o = &osym;
97*5501Slinton 	if (o->strindex == 0) {
98*5501Slinton 		t->symbol = NIL;
99*5501Slinton 	} else {
100*5501Slinton 		t->symbol = &stringtab[o->strindex];
101*5501Slinton 	}
102*5501Slinton 	t->class = o->oclass;
103*5501Slinton 	t->blkno = o->oblkno;
104*5501Slinton 	t->type = (SYM *) o->typno;
105*5501Slinton 	t->chain = (SYM *) o->chno;
106*5501Slinton 	t->symvalue.rangev.lower = o->osymvalue.orangev.lower;
107*5501Slinton 	t->symvalue.rangev.upper = o->osymvalue.orangev.upper;
108*5501Slinton 	if (t->class == RECORD || t->class == VARNT) {
109*5501Slinton 		t->symvalue.varnt.vtorec = (SYM *) o->osymvalue.ovarnt.vtorecno;
110*5501Slinton 		t->symvalue.varnt.vtag = (SYM *) o->osymvalue.ovarnt.vtagno;
111*5501Slinton 	}
112*5501Slinton }
113*5501Slinton 
114*5501Slinton /*
115*5501Slinton  * The symbol read in is a real block so we find it's entry,
116*5501Slinton  * copy the information, and return a pointer to it.
117*5501Slinton  */
118*5501Slinton 
119*5501Slinton LOCAL SYM *findblock(t)
120*5501Slinton SYM *t;
121*5501Slinton {
122*5501Slinton 	SYM *s;
123*5501Slinton 
124*5501Slinton 	s = st_lookup(symtab, t->symbol);
125*5501Slinton 	while (s != NIL &&
126*5501Slinton 	    (s->class != FUNC || s->type != NIL ||
127*5501Slinton 	    strcmp(s->symbol, t->symbol) != 0)) {
128*5501Slinton 		s = s->next_sym;
129*5501Slinton 	}
130*5501Slinton 	if (s == NIL) {
131*5501Slinton 		panic("can't find %s", t->symbol);
132*5501Slinton 	}
133*5501Slinton 	t->next_sym = s->next_sym;
134*5501Slinton 	*s = *t;
135*5501Slinton 	s->symvalue.funcv.codeloc -= BASEADDR;
136*5501Slinton 	findbeginning(s);
137*5501Slinton 	newfunc(s);
138*5501Slinton 	return(s);
139*5501Slinton }
140*5501Slinton 
141*5501Slinton /*
142*5501Slinton  * Found a "fake" block symbol, enter it.
143*5501Slinton  */
144*5501Slinton 
145*5501Slinton LOCAL SYM *enterblock(t)
146*5501Slinton SYM *t;
147*5501Slinton {
148*5501Slinton 	SYM *s;
149*5501Slinton 
150*5501Slinton 	s = st_insert(symtab, t->symbol);
151*5501Slinton 	t->next_sym = s->next_sym;
152*5501Slinton 	*s = *t;
153*5501Slinton 	backpatch();
154*5501Slinton 	s->class = FUNC;
155*5501Slinton 	s->type = NIL;
156*5501Slinton 	return(s);
157*5501Slinton }
158*5501Slinton 
159*5501Slinton /*
160*5501Slinton  * This kludge is brought to you by the pi symbol table.
161*5501Slinton  * Parameters appear with the function in which they reside,
162*5501Slinton  * messing up the way the "func" field is calculated.
163*5501Slinton  *
164*5501Slinton  * The assumption here is that parameters appear before the function.
165*5501Slinton  */
166*5501Slinton 
167*5501Slinton LOCAL fixparams(f)
168*5501Slinton SYM *f;
169*5501Slinton {
170*5501Slinton 	register SYM *s;
171*5501Slinton 
172*5501Slinton 	for (s = f->chain; s != NIL; s = s->chain) {
173*5501Slinton 		s->func = f;
174*5501Slinton 	}
175*5501Slinton }
176*5501Slinton 
177*5501Slinton /*
178*5501Slinton  * Find the function entry associated with a function variable.
179*5501Slinton  * Function variables come out a bit strangely in the symbol table;
180*5501Slinton  * if we didn't do this here, a function variable would have a func
181*5501Slinton  * field that referred to the outer block.
182*5501Slinton  */
183*5501Slinton 
184*5501Slinton #define notfunc(f, fv) (\
185*5501Slinton 	f->class != FUNC || f->type != NIL || \
186*5501Slinton 	strcmp(f->symbol, fv->symbol) != 0 \
187*5501Slinton 	)
188*5501Slinton 
189*5501Slinton LOCAL SYM *findfunc(fv)
190*5501Slinton SYM *fv;
191*5501Slinton {
192*5501Slinton 	register SYM *t;
193*5501Slinton 
194*5501Slinton 	t = st_lookup(symtab, fv->symbol);
195*5501Slinton 	while (t != NIL && notfunc(t, fv)) {
196*5501Slinton 		t = t->next_sym;
197*5501Slinton 	}
198*5501Slinton 	if (t == NIL) {
199*5501Slinton 		panic("no func for funcvar %s", fv->symbol);
200*5501Slinton 	}
201*5501Slinton 	return(t);
202*5501Slinton }
203