1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)readsym.c 1.3 05/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