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