122508Sdist /*
222508Sdist  * Copyright (c) 1980 Regents of the University of California.
322508Sdist  * All rights reserved.  The Berkeley software License Agreement
422508Sdist  * specifies the terms and conditions for redistribution.
522508Sdist  */
65501Slinton 
722508Sdist #ifndef lint
8*30847Smckusick static char sccsid[] = "@(#)readsym.c	5.2 (Berkeley) 04/07/87";
922508Sdist #endif not lint
105501Slinton /*
115501Slinton  * SYM representation dependent routines for reading in the
125501Slinton  * symbol information from the object file.
135501Slinton  */
145501Slinton 
155501Slinton #include "defs.h"
165501Slinton #include "sym.h"
175501Slinton #include "symtab.h"
185501Slinton #include "object.h"
195569Slinton #include "objfmt.h"
205501Slinton #include "process.h"
215501Slinton #include "sym/classes.h"
225501Slinton #include "objsym.rep"
235501Slinton #include "sym/sym.rep"
245501Slinton 
255501Slinton LOCAL SYM *findblock();
265501Slinton LOCAL SYM *enterblock();
275501Slinton LOCAL SYM *findfunc();
285501Slinton 
295501Slinton /*
305501Slinton  * Read the information on a symbol from the object file, return a
315501Slinton  * SYM with the info.
325501Slinton  */
335501Slinton 
345501Slinton SYM *readsym(fp)
355501Slinton FILE *fp;
365501Slinton {
376871Slinton     register SYM *s, *t;
386871Slinton     SYM cursym;
396871Slinton     static SYM *func;
405501Slinton 
416871Slinton     t = &cursym;
426871Slinton     getsym(fp, t);
436871Slinton     if (isblock(t)) {
44*30847Smckusick 	if (t->class == PROG) {
45*30847Smckusick 	    t->symvalue.funcv.codeloc = HEADER_BYTES;
46*30847Smckusick 	}
476871Slinton 	s = findblock(t);
486871Slinton 	if (s->class == PROG) {
496871Slinton 	    program = s;
506871Slinton 	    s->func = NIL;
515501Slinton 	} else {
526871Slinton 	    s->func = func;
535501Slinton 	}
546871Slinton     } else if (t->class == BADUSE) {
556871Slinton 	func = enterblock(t);
566871Slinton 	return(func);
576871Slinton     } else {
586871Slinton 	s = st_insert(symtab, t->symbol);
596871Slinton 	t->next_sym = s->next_sym;
606871Slinton 	*s = *t;
616871Slinton 	if (s->class == FVAR) {
626871Slinton 	    s->func = findfunc(s);
636871Slinton 	} else {
646871Slinton 	    s->func = func;
656871Slinton 	}
666871Slinton     }
675501Slinton 
685501Slinton /*
695501Slinton  * This glitch is pi's fault.  It gives string constants
705501Slinton  * a type whose symbol number is -1.  For what reason, I know not.
715501Slinton  */
726871Slinton     if (s->type == (SYM *) -1) {
736871Slinton 	s->type = NIL;
746871Slinton     } else {
756871Slinton 	chkpatch(&s->type);
766871Slinton     }
776871Slinton     chkpatch(&s->chain);
786871Slinton     if (s->class == RECORD || s->class == VARNT) {
796871Slinton 	chkpatch(&s->symvalue.varnt.vtorec);
806871Slinton 	chkpatch(&s->symvalue.varnt.vtag);
816871Slinton     }
826871Slinton     if (isblock(s)) {
836871Slinton 	fixparams(s);
846871Slinton     }
856871Slinton     return(s);
865501Slinton }
875501Slinton 
885501Slinton /*
895501Slinton  * Read the SYM information in the object file.
905501Slinton  */
915501Slinton 
925501Slinton LOCAL getsym(fp, t)
935501Slinton FILE *fp;
945501Slinton SYM *t;
955501Slinton {
966871Slinton     OBJSYM osym;
976871Slinton     register OBJSYM *o;
985501Slinton 
996871Slinton     get(fp, osym);
1006871Slinton     o = &osym;
1016871Slinton     if (o->strindex == 0) {
1026871Slinton 	t->symbol = NIL;
1036871Slinton     } else {
1046871Slinton 	t->symbol = &stringtab[o->strindex];
1056871Slinton     }
1066871Slinton     t->class = o->oclass;
1076871Slinton     t->blkno = o->oblkno;
1086871Slinton     t->type = (SYM *) o->typno;
1096871Slinton     t->chain = (SYM *) o->chno;
1106871Slinton     t->symvalue.rangev.lower = o->osymvalue.orangev.lower;
1116871Slinton     t->symvalue.rangev.upper = o->osymvalue.orangev.upper;
1126871Slinton     if (t->class == RECORD || t->class == VARNT) {
1136871Slinton 	t->symvalue.varnt.vtorec = (SYM *) o->osymvalue.ovarnt.vtorecno;
1146871Slinton 	t->symvalue.varnt.vtag = (SYM *) o->osymvalue.ovarnt.vtagno;
1156871Slinton     }
1165501Slinton }
1175501Slinton 
1185501Slinton /*
1195501Slinton  * The symbol read in is a real block so we find it's entry,
1205501Slinton  * copy the information, and return a pointer to it.
1215501Slinton  */
1225501Slinton 
1235501Slinton LOCAL SYM *findblock(t)
1245501Slinton SYM *t;
1255501Slinton {
1266871Slinton     SYM *s;
1275501Slinton 
1286871Slinton     s = st_lookup(symtab, t->symbol);
1296871Slinton     while (s != NIL &&
1306871Slinton 	(s->class != FUNC || s->type != NIL ||
1316871Slinton 	strcmp(s->symbol, t->symbol) != 0)) {
1326871Slinton 	s = s->next_sym;
1336871Slinton     }
1346871Slinton     if (s == NIL) {
1356871Slinton 	panic("can't find %s", t->symbol);
1366871Slinton     }
1376871Slinton     t->next_sym = s->next_sym;
1386871Slinton     *s = *t;
1396871Slinton     s->symvalue.funcv.codeloc -= HEADER_BYTES;
1406871Slinton     findbeginning(s);
1416871Slinton     newfunc(s);
1426871Slinton     return(s);
1435501Slinton }
1445501Slinton 
1455501Slinton /*
1465501Slinton  * Found a "fake" block symbol, enter it.
1475501Slinton  */
1485501Slinton 
1495501Slinton LOCAL SYM *enterblock(t)
1505501Slinton SYM *t;
1515501Slinton {
1526871Slinton     SYM *s;
1535501Slinton 
1546871Slinton     s = st_insert(symtab, t->symbol);
1556871Slinton     t->next_sym = s->next_sym;
1566871Slinton     *s = *t;
1576871Slinton     backpatch();
1586871Slinton     s->class = FUNC;
1596871Slinton     s->type = NIL;
1606871Slinton     return(s);
1615501Slinton }
1625501Slinton 
1635501Slinton /*
1645501Slinton  * This kludge is brought to you by the pi symbol table.
1655501Slinton  * Parameters appear with the function in which they reside,
1665501Slinton  * messing up the way the "func" field is calculated.
1675501Slinton  *
1685501Slinton  * The assumption here is that parameters appear before the function.
1695501Slinton  */
1705501Slinton 
1715501Slinton LOCAL fixparams(f)
1725501Slinton SYM *f;
1735501Slinton {
1746871Slinton     register SYM *s;
1755501Slinton 
1766871Slinton     for (s = f->chain; s != NIL; s = s->chain) {
1776871Slinton 	s->func = f;
1786871Slinton     }
1795501Slinton }
1805501Slinton 
1815501Slinton /*
1825501Slinton  * Find the function entry associated with a function variable.
1835501Slinton  * Function variables come out a bit strangely in the symbol table;
1845501Slinton  * if we didn't do this here, a function variable would have a func
1855501Slinton  * field that referred to the outer block.
1865501Slinton  */
1875501Slinton 
1885501Slinton #define notfunc(f, fv) (\
1896871Slinton     f->class != FUNC || f->type != NIL || \
1906871Slinton     strcmp(f->symbol, fv->symbol) != 0 \
1916871Slinton     )
1925501Slinton 
1935501Slinton LOCAL SYM *findfunc(fv)
1945501Slinton SYM *fv;
1955501Slinton {
1966871Slinton     register SYM *t;
1975501Slinton 
1986871Slinton     t = st_lookup(symtab, fv->symbol);
1996871Slinton     while (t != NIL && notfunc(t, fv)) {
2006871Slinton 	t = t->next_sym;
2016871Slinton     }
2026871Slinton     if (t == NIL) {
2036871Slinton 	panic("no func for funcvar %s", fv->symbol);
2046871Slinton     }
2056871Slinton     return(t);
2065501Slinton }
207