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