148097Sbostic /*-
2*62142Sbostic  * Copyright (c) 1980, 1993
3*62142Sbostic  *	The Regents of the University of California.  All rights reserved.
448097Sbostic  *
548097Sbostic  * %sccs.include.redist.c%
622508Sdist  */
75501Slinton 
822508Sdist #ifndef lint
9*62142Sbostic static char sccsid[] = "@(#)readsym.c	8.1 (Berkeley) 06/06/93";
1048097Sbostic #endif /* not lint */
1148097Sbostic 
125501Slinton /*
135501Slinton  * SYM representation dependent routines for reading in the
145501Slinton  * symbol information from the object file.
155501Slinton  */
165501Slinton 
175501Slinton #include "defs.h"
185501Slinton #include "sym.h"
195501Slinton #include "symtab.h"
205501Slinton #include "object.h"
215569Slinton #include "objfmt.h"
225501Slinton #include "process.h"
235501Slinton #include "sym/classes.h"
245501Slinton #include "objsym.rep"
255501Slinton #include "sym/sym.rep"
265501Slinton 
275501Slinton LOCAL SYM *findblock();
285501Slinton LOCAL SYM *enterblock();
295501Slinton LOCAL SYM *findfunc();
305501Slinton 
315501Slinton /*
325501Slinton  * Read the information on a symbol from the object file, return a
335501Slinton  * SYM with the info.
345501Slinton  */
355501Slinton 
readsym(fp)365501Slinton SYM *readsym(fp)
375501Slinton FILE *fp;
385501Slinton {
396871Slinton     register SYM *s, *t;
406871Slinton     SYM cursym;
416871Slinton     static SYM *func;
425501Slinton 
436871Slinton     t = &cursym;
446871Slinton     getsym(fp, t);
456871Slinton     if (isblock(t)) {
4630847Smckusick 	if (t->class == PROG) {
4730847Smckusick 	    t->symvalue.funcv.codeloc = HEADER_BYTES;
4830847Smckusick 	}
496871Slinton 	s = findblock(t);
506871Slinton 	if (s->class == PROG) {
516871Slinton 	    program = s;
526871Slinton 	    s->func = NIL;
535501Slinton 	} else {
546871Slinton 	    s->func = func;
555501Slinton 	}
566871Slinton     } else if (t->class == BADUSE) {
576871Slinton 	func = enterblock(t);
586871Slinton 	return(func);
596871Slinton     } else {
606871Slinton 	s = st_insert(symtab, t->symbol);
616871Slinton 	t->next_sym = s->next_sym;
626871Slinton 	*s = *t;
636871Slinton 	if (s->class == FVAR) {
646871Slinton 	    s->func = findfunc(s);
656871Slinton 	} else {
666871Slinton 	    s->func = func;
676871Slinton 	}
686871Slinton     }
695501Slinton 
705501Slinton /*
715501Slinton  * This glitch is pi's fault.  It gives string constants
725501Slinton  * a type whose symbol number is -1.  For what reason, I know not.
735501Slinton  */
746871Slinton     if (s->type == (SYM *) -1) {
756871Slinton 	s->type = NIL;
766871Slinton     } else {
776871Slinton 	chkpatch(&s->type);
786871Slinton     }
796871Slinton     chkpatch(&s->chain);
806871Slinton     if (s->class == RECORD || s->class == VARNT) {
816871Slinton 	chkpatch(&s->symvalue.varnt.vtorec);
826871Slinton 	chkpatch(&s->symvalue.varnt.vtag);
836871Slinton     }
846871Slinton     if (isblock(s)) {
856871Slinton 	fixparams(s);
866871Slinton     }
876871Slinton     return(s);
885501Slinton }
895501Slinton 
905501Slinton /*
915501Slinton  * Read the SYM information in the object file.
925501Slinton  */
935501Slinton 
getsym(fp,t)945501Slinton LOCAL getsym(fp, t)
955501Slinton FILE *fp;
965501Slinton SYM *t;
975501Slinton {
986871Slinton     OBJSYM osym;
996871Slinton     register OBJSYM *o;
1005501Slinton 
1016871Slinton     get(fp, osym);
1026871Slinton     o = &osym;
1036871Slinton     if (o->strindex == 0) {
1046871Slinton 	t->symbol = NIL;
1056871Slinton     } else {
1066871Slinton 	t->symbol = &stringtab[o->strindex];
1076871Slinton     }
1086871Slinton     t->class = o->oclass;
1096871Slinton     t->blkno = o->oblkno;
1106871Slinton     t->type = (SYM *) o->typno;
1116871Slinton     t->chain = (SYM *) o->chno;
1126871Slinton     t->symvalue.rangev.lower = o->osymvalue.orangev.lower;
1136871Slinton     t->symvalue.rangev.upper = o->osymvalue.orangev.upper;
1146871Slinton     if (t->class == RECORD || t->class == VARNT) {
1156871Slinton 	t->symvalue.varnt.vtorec = (SYM *) o->osymvalue.ovarnt.vtorecno;
1166871Slinton 	t->symvalue.varnt.vtag = (SYM *) o->osymvalue.ovarnt.vtagno;
1176871Slinton     }
1185501Slinton }
1195501Slinton 
1205501Slinton /*
1215501Slinton  * The symbol read in is a real block so we find it's entry,
1225501Slinton  * copy the information, and return a pointer to it.
1235501Slinton  */
1245501Slinton 
findblock(t)1255501Slinton LOCAL SYM *findblock(t)
1265501Slinton SYM *t;
1275501Slinton {
1286871Slinton     SYM *s;
1295501Slinton 
1306871Slinton     s = st_lookup(symtab, t->symbol);
1316871Slinton     while (s != NIL &&
1326871Slinton 	(s->class != FUNC || s->type != NIL ||
1336871Slinton 	strcmp(s->symbol, t->symbol) != 0)) {
1346871Slinton 	s = s->next_sym;
1356871Slinton     }
1366871Slinton     if (s == NIL) {
1376871Slinton 	panic("can't find %s", t->symbol);
1386871Slinton     }
1396871Slinton     t->next_sym = s->next_sym;
1406871Slinton     *s = *t;
1416871Slinton     s->symvalue.funcv.codeloc -= HEADER_BYTES;
1426871Slinton     findbeginning(s);
1436871Slinton     newfunc(s);
1446871Slinton     return(s);
1455501Slinton }
1465501Slinton 
1475501Slinton /*
1485501Slinton  * Found a "fake" block symbol, enter it.
1495501Slinton  */
1505501Slinton 
enterblock(t)1515501Slinton LOCAL SYM *enterblock(t)
1525501Slinton SYM *t;
1535501Slinton {
1546871Slinton     SYM *s;
1555501Slinton 
1566871Slinton     s = st_insert(symtab, t->symbol);
1576871Slinton     t->next_sym = s->next_sym;
1586871Slinton     *s = *t;
1596871Slinton     backpatch();
1606871Slinton     s->class = FUNC;
1616871Slinton     s->type = NIL;
1626871Slinton     return(s);
1635501Slinton }
1645501Slinton 
1655501Slinton /*
1665501Slinton  * This kludge is brought to you by the pi symbol table.
1675501Slinton  * Parameters appear with the function in which they reside,
1685501Slinton  * messing up the way the "func" field is calculated.
1695501Slinton  *
1705501Slinton  * The assumption here is that parameters appear before the function.
1715501Slinton  */
1725501Slinton 
fixparams(f)1735501Slinton LOCAL fixparams(f)
1745501Slinton SYM *f;
1755501Slinton {
1766871Slinton     register SYM *s;
1775501Slinton 
1786871Slinton     for (s = f->chain; s != NIL; s = s->chain) {
1796871Slinton 	s->func = f;
1806871Slinton     }
1815501Slinton }
1825501Slinton 
1835501Slinton /*
1845501Slinton  * Find the function entry associated with a function variable.
1855501Slinton  * Function variables come out a bit strangely in the symbol table;
1865501Slinton  * if we didn't do this here, a function variable would have a func
1875501Slinton  * field that referred to the outer block.
1885501Slinton  */
1895501Slinton 
1905501Slinton #define notfunc(f, fv) (\
1916871Slinton     f->class != FUNC || f->type != NIL || \
1926871Slinton     strcmp(f->symbol, fv->symbol) != 0 \
1936871Slinton     )
1945501Slinton 
findfunc(fv)1955501Slinton LOCAL SYM *findfunc(fv)
1965501Slinton SYM *fv;
1975501Slinton {
1986871Slinton     register SYM *t;
1995501Slinton 
2006871Slinton     t = st_lookup(symtab, fv->symbol);
2016871Slinton     while (t != NIL && notfunc(t, fv)) {
2026871Slinton 	t = t->next_sym;
2036871Slinton     }
2046871Slinton     if (t == NIL) {
2056871Slinton 	panic("no func for funcvar %s", fv->symbol);
2066871Slinton     }
2076871Slinton     return(t);
2085501Slinton }
209