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