1*22508Sdist /* 2*22508Sdist * Copyright (c) 1980 Regents of the University of California. 3*22508Sdist * All rights reserved. The Berkeley software License Agreement 4*22508Sdist * specifies the terms and conditions for redistribution. 5*22508Sdist */ 65501Slinton 7*22508Sdist #ifndef lint 8*22508Sdist static char sccsid[] = "@(#)readsym.c 5.1 (Berkeley) 06/06/85"; 9*22508Sdist #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)) { 446871Slinton # if (isvaxpx) 456871Slinton if (t->class == PROG) { 466871Slinton t->symvalue.funcv.codeloc = HEADER_BYTES; 476871Slinton } 486871Slinton # endif 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 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 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 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 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 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