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