15501Slinton /* Copyright (c) 1982 Regents of the University of California */
25501Slinton 
3*5569Slinton static char sccsid[] = "@(#)readsym.c 1.2 01/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"
14*5569Slinton #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 {
325501Slinton 	register SYM *s, *t;
335501Slinton 	SYM cursym;
345501Slinton 	static SYM *func;
355501Slinton 
365501Slinton 	t = &cursym;
375501Slinton 	getsym(fp, t);
385501Slinton 	if (isblock(t)) {
395501Slinton #		if (isvaxpx)
405501Slinton 			if (t->class == PROG) {
41*5569Slinton 				t->symvalue.funcv.codeloc = HEADER_BYTES;
425501Slinton 			}
435501Slinton #		endif
445501Slinton 		s = findblock(t);
455501Slinton 		if (s->class == PROG) {
465501Slinton 			program = s;
475501Slinton 			s->func = NIL;
485501Slinton 		} else {
495501Slinton 			s->func = func;
505501Slinton 		}
515501Slinton 	} else if (t->class == BADUSE) {
525501Slinton 		func = enterblock(t);
535501Slinton 		return(func);
545501Slinton 	} else {
555501Slinton 		s = st_insert(symtab, t->symbol);
565501Slinton 		t->next_sym = s->next_sym;
575501Slinton 		*s = *t;
585501Slinton 		if (s->class == FVAR) {
595501Slinton 			s->func = findfunc(s);
605501Slinton 		} else {
615501Slinton 			s->func = func;
625501Slinton 		}
635501Slinton 	}
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  */
695501Slinton 	if (s->type == (SYM *) -1) {
705501Slinton 		s->type = NIL;
715501Slinton 	} else {
725501Slinton 		chkpatch(&s->type);
735501Slinton 	}
745501Slinton 	chkpatch(&s->chain);
755501Slinton 	if (s->class == RECORD || s->class == VARNT) {
765501Slinton 		chkpatch(&s->symvalue.varnt.vtorec);
775501Slinton 		chkpatch(&s->symvalue.varnt.vtag);
785501Slinton 	}
795501Slinton 	if (isblock(s)) {
805501Slinton 		fixparams(s);
815501Slinton 	}
825501Slinton 	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 {
935501Slinton 	OBJSYM osym;
945501Slinton 	register OBJSYM *o;
955501Slinton 
965501Slinton 	get(fp, osym);
975501Slinton 	o = &osym;
985501Slinton 	if (o->strindex == 0) {
995501Slinton 		t->symbol = NIL;
1005501Slinton 	} else {
1015501Slinton 		t->symbol = &stringtab[o->strindex];
1025501Slinton 	}
1035501Slinton 	t->class = o->oclass;
1045501Slinton 	t->blkno = o->oblkno;
1055501Slinton 	t->type = (SYM *) o->typno;
1065501Slinton 	t->chain = (SYM *) o->chno;
1075501Slinton 	t->symvalue.rangev.lower = o->osymvalue.orangev.lower;
1085501Slinton 	t->symvalue.rangev.upper = o->osymvalue.orangev.upper;
1095501Slinton 	if (t->class == RECORD || t->class == VARNT) {
1105501Slinton 		t->symvalue.varnt.vtorec = (SYM *) o->osymvalue.ovarnt.vtorecno;
1115501Slinton 		t->symvalue.varnt.vtag = (SYM *) o->osymvalue.ovarnt.vtagno;
1125501Slinton 	}
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 {
1235501Slinton 	SYM *s;
1245501Slinton 
1255501Slinton 	s = st_lookup(symtab, t->symbol);
1265501Slinton 	while (s != NIL &&
1275501Slinton 	    (s->class != FUNC || s->type != NIL ||
1285501Slinton 	    strcmp(s->symbol, t->symbol) != 0)) {
1295501Slinton 		s = s->next_sym;
1305501Slinton 	}
1315501Slinton 	if (s == NIL) {
1325501Slinton 		panic("can't find %s", t->symbol);
1335501Slinton 	}
1345501Slinton 	t->next_sym = s->next_sym;
1355501Slinton 	*s = *t;
136*5569Slinton 	s->symvalue.funcv.codeloc -= HEADER_BYTES;
1375501Slinton 	findbeginning(s);
1385501Slinton 	newfunc(s);
1395501Slinton 	return(s);
1405501Slinton }
1415501Slinton 
1425501Slinton /*
1435501Slinton  * Found a "fake" block symbol, enter it.
1445501Slinton  */
1455501Slinton 
1465501Slinton LOCAL SYM *enterblock(t)
1475501Slinton SYM *t;
1485501Slinton {
1495501Slinton 	SYM *s;
1505501Slinton 
1515501Slinton 	s = st_insert(symtab, t->symbol);
1525501Slinton 	t->next_sym = s->next_sym;
1535501Slinton 	*s = *t;
1545501Slinton 	backpatch();
1555501Slinton 	s->class = FUNC;
1565501Slinton 	s->type = NIL;
1575501Slinton 	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 {
1715501Slinton 	register SYM *s;
1725501Slinton 
1735501Slinton 	for (s = f->chain; s != NIL; s = s->chain) {
1745501Slinton 		s->func = f;
1755501Slinton 	}
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) (\
1865501Slinton 	f->class != FUNC || f->type != NIL || \
1875501Slinton 	strcmp(f->symbol, fv->symbol) != 0 \
1885501Slinton 	)
1895501Slinton 
1905501Slinton LOCAL SYM *findfunc(fv)
1915501Slinton SYM *fv;
1925501Slinton {
1935501Slinton 	register SYM *t;
1945501Slinton 
1955501Slinton 	t = st_lookup(symtab, fv->symbol);
1965501Slinton 	while (t != NIL && notfunc(t, fv)) {
1975501Slinton 		t = t->next_sym;
1985501Slinton 	}
1995501Slinton 	if (t == NIL) {
2005501Slinton 		panic("no func for funcvar %s", fv->symbol);
2015501Slinton 	}
2025501Slinton 	return(t);
2035501Slinton }
204