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