1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)readsym.c 5.2 (Berkeley) 04/07/87"; 9 #endif not lint 10 /* 11 * SYM representation dependent routines for reading in the 12 * symbol information from the object file. 13 */ 14 15 #include "defs.h" 16 #include "sym.h" 17 #include "symtab.h" 18 #include "object.h" 19 #include "objfmt.h" 20 #include "process.h" 21 #include "sym/classes.h" 22 #include "objsym.rep" 23 #include "sym/sym.rep" 24 25 LOCAL SYM *findblock(); 26 LOCAL SYM *enterblock(); 27 LOCAL SYM *findfunc(); 28 29 /* 30 * Read the information on a symbol from the object file, return a 31 * SYM with the info. 32 */ 33 34 SYM *readsym(fp) 35 FILE *fp; 36 { 37 register SYM *s, *t; 38 SYM cursym; 39 static SYM *func; 40 41 t = &cursym; 42 getsym(fp, t); 43 if (isblock(t)) { 44 if (t->class == PROG) { 45 t->symvalue.funcv.codeloc = HEADER_BYTES; 46 } 47 s = findblock(t); 48 if (s->class == PROG) { 49 program = s; 50 s->func = NIL; 51 } else { 52 s->func = func; 53 } 54 } else if (t->class == BADUSE) { 55 func = enterblock(t); 56 return(func); 57 } else { 58 s = st_insert(symtab, t->symbol); 59 t->next_sym = s->next_sym; 60 *s = *t; 61 if (s->class == FVAR) { 62 s->func = findfunc(s); 63 } else { 64 s->func = func; 65 } 66 } 67 68 /* 69 * This glitch is pi's fault. It gives string constants 70 * a type whose symbol number is -1. For what reason, I know not. 71 */ 72 if (s->type == (SYM *) -1) { 73 s->type = NIL; 74 } else { 75 chkpatch(&s->type); 76 } 77 chkpatch(&s->chain); 78 if (s->class == RECORD || s->class == VARNT) { 79 chkpatch(&s->symvalue.varnt.vtorec); 80 chkpatch(&s->symvalue.varnt.vtag); 81 } 82 if (isblock(s)) { 83 fixparams(s); 84 } 85 return(s); 86 } 87 88 /* 89 * Read the SYM information in the object file. 90 */ 91 92 LOCAL getsym(fp, t) 93 FILE *fp; 94 SYM *t; 95 { 96 OBJSYM osym; 97 register OBJSYM *o; 98 99 get(fp, osym); 100 o = &osym; 101 if (o->strindex == 0) { 102 t->symbol = NIL; 103 } else { 104 t->symbol = &stringtab[o->strindex]; 105 } 106 t->class = o->oclass; 107 t->blkno = o->oblkno; 108 t->type = (SYM *) o->typno; 109 t->chain = (SYM *) o->chno; 110 t->symvalue.rangev.lower = o->osymvalue.orangev.lower; 111 t->symvalue.rangev.upper = o->osymvalue.orangev.upper; 112 if (t->class == RECORD || t->class == VARNT) { 113 t->symvalue.varnt.vtorec = (SYM *) o->osymvalue.ovarnt.vtorecno; 114 t->symvalue.varnt.vtag = (SYM *) o->osymvalue.ovarnt.vtagno; 115 } 116 } 117 118 /* 119 * The symbol read in is a real block so we find it's entry, 120 * copy the information, and return a pointer to it. 121 */ 122 123 LOCAL SYM *findblock(t) 124 SYM *t; 125 { 126 SYM *s; 127 128 s = st_lookup(symtab, t->symbol); 129 while (s != NIL && 130 (s->class != FUNC || s->type != NIL || 131 strcmp(s->symbol, t->symbol) != 0)) { 132 s = s->next_sym; 133 } 134 if (s == NIL) { 135 panic("can't find %s", t->symbol); 136 } 137 t->next_sym = s->next_sym; 138 *s = *t; 139 s->symvalue.funcv.codeloc -= HEADER_BYTES; 140 findbeginning(s); 141 newfunc(s); 142 return(s); 143 } 144 145 /* 146 * Found a "fake" block symbol, enter it. 147 */ 148 149 LOCAL SYM *enterblock(t) 150 SYM *t; 151 { 152 SYM *s; 153 154 s = st_insert(symtab, t->symbol); 155 t->next_sym = s->next_sym; 156 *s = *t; 157 backpatch(); 158 s->class = FUNC; 159 s->type = NIL; 160 return(s); 161 } 162 163 /* 164 * This kludge is brought to you by the pi symbol table. 165 * Parameters appear with the function in which they reside, 166 * messing up the way the "func" field is calculated. 167 * 168 * The assumption here is that parameters appear before the function. 169 */ 170 171 LOCAL fixparams(f) 172 SYM *f; 173 { 174 register SYM *s; 175 176 for (s = f->chain; s != NIL; s = s->chain) { 177 s->func = f; 178 } 179 } 180 181 /* 182 * Find the function entry associated with a function variable. 183 * Function variables come out a bit strangely in the symbol table; 184 * if we didn't do this here, a function variable would have a func 185 * field that referred to the outer block. 186 */ 187 188 #define notfunc(f, fv) (\ 189 f->class != FUNC || f->type != NIL || \ 190 strcmp(f->symbol, fv->symbol) != 0 \ 191 ) 192 193 LOCAL SYM *findfunc(fv) 194 SYM *fv; 195 { 196 register SYM *t; 197 198 t = st_lookup(symtab, fv->symbol); 199 while (t != NIL && notfunc(t, fv)) { 200 t = t->next_sym; 201 } 202 if (t == NIL) { 203 panic("no func for funcvar %s", fv->symbol); 204 } 205 return(t); 206 } 207