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.1 (Berkeley) 06/06/85"; 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 (isvaxpx) 45 if (t->class == PROG) { 46 t->symvalue.funcv.codeloc = HEADER_BYTES; 47 } 48 # endif 49 s = findblock(t); 50 if (s->class == PROG) { 51 program = s; 52 s->func = NIL; 53 } else { 54 s->func = func; 55 } 56 } else if (t->class == BADUSE) { 57 func = enterblock(t); 58 return(func); 59 } else { 60 s = st_insert(symtab, t->symbol); 61 t->next_sym = s->next_sym; 62 *s = *t; 63 if (s->class == FVAR) { 64 s->func = findfunc(s); 65 } else { 66 s->func = func; 67 } 68 } 69 70 /* 71 * This glitch is pi's fault. It gives string constants 72 * a type whose symbol number is -1. For what reason, I know not. 73 */ 74 if (s->type == (SYM *) -1) { 75 s->type = NIL; 76 } else { 77 chkpatch(&s->type); 78 } 79 chkpatch(&s->chain); 80 if (s->class == RECORD || s->class == VARNT) { 81 chkpatch(&s->symvalue.varnt.vtorec); 82 chkpatch(&s->symvalue.varnt.vtag); 83 } 84 if (isblock(s)) { 85 fixparams(s); 86 } 87 return(s); 88 } 89 90 /* 91 * Read the SYM information in the object file. 92 */ 93 94 LOCAL getsym(fp, t) 95 FILE *fp; 96 SYM *t; 97 { 98 OBJSYM osym; 99 register OBJSYM *o; 100 101 get(fp, osym); 102 o = &osym; 103 if (o->strindex == 0) { 104 t->symbol = NIL; 105 } else { 106 t->symbol = &stringtab[o->strindex]; 107 } 108 t->class = o->oclass; 109 t->blkno = o->oblkno; 110 t->type = (SYM *) o->typno; 111 t->chain = (SYM *) o->chno; 112 t->symvalue.rangev.lower = o->osymvalue.orangev.lower; 113 t->symvalue.rangev.upper = o->osymvalue.orangev.upper; 114 if (t->class == RECORD || t->class == VARNT) { 115 t->symvalue.varnt.vtorec = (SYM *) o->osymvalue.ovarnt.vtorecno; 116 t->symvalue.varnt.vtag = (SYM *) o->osymvalue.ovarnt.vtagno; 117 } 118 } 119 120 /* 121 * The symbol read in is a real block so we find it's entry, 122 * copy the information, and return a pointer to it. 123 */ 124 125 LOCAL SYM *findblock(t) 126 SYM *t; 127 { 128 SYM *s; 129 130 s = st_lookup(symtab, t->symbol); 131 while (s != NIL && 132 (s->class != FUNC || s->type != NIL || 133 strcmp(s->symbol, t->symbol) != 0)) { 134 s = s->next_sym; 135 } 136 if (s == NIL) { 137 panic("can't find %s", t->symbol); 138 } 139 t->next_sym = s->next_sym; 140 *s = *t; 141 s->symvalue.funcv.codeloc -= HEADER_BYTES; 142 findbeginning(s); 143 newfunc(s); 144 return(s); 145 } 146 147 /* 148 * Found a "fake" block symbol, enter it. 149 */ 150 151 LOCAL SYM *enterblock(t) 152 SYM *t; 153 { 154 SYM *s; 155 156 s = st_insert(symtab, t->symbol); 157 t->next_sym = s->next_sym; 158 *s = *t; 159 backpatch(); 160 s->class = FUNC; 161 s->type = NIL; 162 return(s); 163 } 164 165 /* 166 * This kludge is brought to you by the pi symbol table. 167 * Parameters appear with the function in which they reside, 168 * messing up the way the "func" field is calculated. 169 * 170 * The assumption here is that parameters appear before the function. 171 */ 172 173 LOCAL fixparams(f) 174 SYM *f; 175 { 176 register SYM *s; 177 178 for (s = f->chain; s != NIL; s = s->chain) { 179 s->func = f; 180 } 181 } 182 183 /* 184 * Find the function entry associated with a function variable. 185 * Function variables come out a bit strangely in the symbol table; 186 * if we didn't do this here, a function variable would have a func 187 * field that referred to the outer block. 188 */ 189 190 #define notfunc(f, fv) (\ 191 f->class != FUNC || f->type != NIL || \ 192 strcmp(f->symbol, fv->symbol) != 0 \ 193 ) 194 195 LOCAL SYM *findfunc(fv) 196 SYM *fv; 197 { 198 register SYM *t; 199 200 t = st_lookup(symtab, fv->symbol); 201 while (t != NIL && notfunc(t, fv)) { 202 t = t->next_sym; 203 } 204 if (t == NIL) { 205 panic("no func for funcvar %s", fv->symbol); 206 } 207 return(t); 208 } 209