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