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