15501Slinton /* Copyright (c) 1982 Regents of the University of California */
25501Slinton 
3*6871Slinton static char sccsid[] = "@(#)readsym.c 1.3 05/19/82";
45501Slinton 
55501Slinton /*
65501Slinton  * SYM representation dependent routines for reading in the
75501Slinton  * symbol information from the object file.
85501Slinton  */
95501Slinton 
105501Slinton #include "defs.h"
115501Slinton #include "sym.h"
125501Slinton #include "symtab.h"
135501Slinton #include "object.h"
145569Slinton #include "objfmt.h"
155501Slinton #include "process.h"
165501Slinton #include "sym/classes.h"
175501Slinton #include "objsym.rep"
185501Slinton #include "sym/sym.rep"
195501Slinton 
205501Slinton LOCAL SYM *findblock();
215501Slinton LOCAL SYM *enterblock();
225501Slinton LOCAL SYM *findfunc();
235501Slinton 
245501Slinton /*
255501Slinton  * Read the information on a symbol from the object file, return a
265501Slinton  * SYM with the info.
275501Slinton  */
285501Slinton 
295501Slinton SYM *readsym(fp)
305501Slinton FILE *fp;
315501Slinton {
32*6871Slinton     register SYM *s, *t;
33*6871Slinton     SYM cursym;
34*6871Slinton     static SYM *func;
355501Slinton 
36*6871Slinton     t = &cursym;
37*6871Slinton     getsym(fp, t);
38*6871Slinton     if (isblock(t)) {
39*6871Slinton #       if (isvaxpx)
40*6871Slinton 	    if (t->class == PROG) {
41*6871Slinton 		t->symvalue.funcv.codeloc = HEADER_BYTES;
42*6871Slinton 	    }
43*6871Slinton #       endif
44*6871Slinton 	s = findblock(t);
45*6871Slinton 	if (s->class == PROG) {
46*6871Slinton 	    program = s;
47*6871Slinton 	    s->func = NIL;
485501Slinton 	} else {
49*6871Slinton 	    s->func = func;
505501Slinton 	}
51*6871Slinton     } else if (t->class == BADUSE) {
52*6871Slinton 	func = enterblock(t);
53*6871Slinton 	return(func);
54*6871Slinton     } else {
55*6871Slinton 	s = st_insert(symtab, t->symbol);
56*6871Slinton 	t->next_sym = s->next_sym;
57*6871Slinton 	*s = *t;
58*6871Slinton 	if (s->class == FVAR) {
59*6871Slinton 	    s->func = findfunc(s);
60*6871Slinton 	} else {
61*6871Slinton 	    s->func = func;
62*6871Slinton 	}
63*6871Slinton     }
645501Slinton 
655501Slinton /*
665501Slinton  * This glitch is pi's fault.  It gives string constants
675501Slinton  * a type whose symbol number is -1.  For what reason, I know not.
685501Slinton  */
69*6871Slinton     if (s->type == (SYM *) -1) {
70*6871Slinton 	s->type = NIL;
71*6871Slinton     } else {
72*6871Slinton 	chkpatch(&s->type);
73*6871Slinton     }
74*6871Slinton     chkpatch(&s->chain);
75*6871Slinton     if (s->class == RECORD || s->class == VARNT) {
76*6871Slinton 	chkpatch(&s->symvalue.varnt.vtorec);
77*6871Slinton 	chkpatch(&s->symvalue.varnt.vtag);
78*6871Slinton     }
79*6871Slinton     if (isblock(s)) {
80*6871Slinton 	fixparams(s);
81*6871Slinton     }
82*6871Slinton     return(s);
835501Slinton }
845501Slinton 
855501Slinton /*
865501Slinton  * Read the SYM information in the object file.
875501Slinton  */
885501Slinton 
895501Slinton LOCAL getsym(fp, t)
905501Slinton FILE *fp;
915501Slinton SYM *t;
925501Slinton {
93*6871Slinton     OBJSYM osym;
94*6871Slinton     register OBJSYM *o;
955501Slinton 
96*6871Slinton     get(fp, osym);
97*6871Slinton     o = &osym;
98*6871Slinton     if (o->strindex == 0) {
99*6871Slinton 	t->symbol = NIL;
100*6871Slinton     } else {
101*6871Slinton 	t->symbol = &stringtab[o->strindex];
102*6871Slinton     }
103*6871Slinton     t->class = o->oclass;
104*6871Slinton     t->blkno = o->oblkno;
105*6871Slinton     t->type = (SYM *) o->typno;
106*6871Slinton     t->chain = (SYM *) o->chno;
107*6871Slinton     t->symvalue.rangev.lower = o->osymvalue.orangev.lower;
108*6871Slinton     t->symvalue.rangev.upper = o->osymvalue.orangev.upper;
109*6871Slinton     if (t->class == RECORD || t->class == VARNT) {
110*6871Slinton 	t->symvalue.varnt.vtorec = (SYM *) o->osymvalue.ovarnt.vtorecno;
111*6871Slinton 	t->symvalue.varnt.vtag = (SYM *) o->osymvalue.ovarnt.vtagno;
112*6871Slinton     }
1135501Slinton }
1145501Slinton 
1155501Slinton /*
1165501Slinton  * The symbol read in is a real block so we find it's entry,
1175501Slinton  * copy the information, and return a pointer to it.
1185501Slinton  */
1195501Slinton 
1205501Slinton LOCAL SYM *findblock(t)
1215501Slinton SYM *t;
1225501Slinton {
123*6871Slinton     SYM *s;
1245501Slinton 
125*6871Slinton     s = st_lookup(symtab, t->symbol);
126*6871Slinton     while (s != NIL &&
127*6871Slinton 	(s->class != FUNC || s->type != NIL ||
128*6871Slinton 	strcmp(s->symbol, t->symbol) != 0)) {
129*6871Slinton 	s = s->next_sym;
130*6871Slinton     }
131*6871Slinton     if (s == NIL) {
132*6871Slinton 	panic("can't find %s", t->symbol);
133*6871Slinton     }
134*6871Slinton     t->next_sym = s->next_sym;
135*6871Slinton     *s = *t;
136*6871Slinton     s->symvalue.funcv.codeloc -= HEADER_BYTES;
137*6871Slinton     findbeginning(s);
138*6871Slinton     newfunc(s);
139*6871Slinton     return(s);
1405501Slinton }
1415501Slinton 
1425501Slinton /*
1435501Slinton  * Found a "fake" block symbol, enter it.
1445501Slinton  */
1455501Slinton 
1465501Slinton LOCAL SYM *enterblock(t)
1475501Slinton SYM *t;
1485501Slinton {
149*6871Slinton     SYM *s;
1505501Slinton 
151*6871Slinton     s = st_insert(symtab, t->symbol);
152*6871Slinton     t->next_sym = s->next_sym;
153*6871Slinton     *s = *t;
154*6871Slinton     backpatch();
155*6871Slinton     s->class = FUNC;
156*6871Slinton     s->type = NIL;
157*6871Slinton     return(s);
1585501Slinton }
1595501Slinton 
1605501Slinton /*
1615501Slinton  * This kludge is brought to you by the pi symbol table.
1625501Slinton  * Parameters appear with the function in which they reside,
1635501Slinton  * messing up the way the "func" field is calculated.
1645501Slinton  *
1655501Slinton  * The assumption here is that parameters appear before the function.
1665501Slinton  */
1675501Slinton 
1685501Slinton LOCAL fixparams(f)
1695501Slinton SYM *f;
1705501Slinton {
171*6871Slinton     register SYM *s;
1725501Slinton 
173*6871Slinton     for (s = f->chain; s != NIL; s = s->chain) {
174*6871Slinton 	s->func = f;
175*6871Slinton     }
1765501Slinton }
1775501Slinton 
1785501Slinton /*
1795501Slinton  * Find the function entry associated with a function variable.
1805501Slinton  * Function variables come out a bit strangely in the symbol table;
1815501Slinton  * if we didn't do this here, a function variable would have a func
1825501Slinton  * field that referred to the outer block.
1835501Slinton  */
1845501Slinton 
1855501Slinton #define notfunc(f, fv) (\
186*6871Slinton     f->class != FUNC || f->type != NIL || \
187*6871Slinton     strcmp(f->symbol, fv->symbol) != 0 \
188*6871Slinton     )
1895501Slinton 
1905501Slinton LOCAL SYM *findfunc(fv)
1915501Slinton SYM *fv;
1925501Slinton {
193*6871Slinton     register SYM *t;
1945501Slinton 
195*6871Slinton     t = st_lookup(symtab, fv->symbol);
196*6871Slinton     while (t != NIL && notfunc(t, fv)) {
197*6871Slinton 	t = t->next_sym;
198*6871Slinton     }
199*6871Slinton     if (t == NIL) {
200*6871Slinton 	panic("no func for funcvar %s", fv->symbol);
201*6871Slinton     }
202*6871Slinton     return(t);
2035501Slinton }
204