1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)readobj.c 1.1 01/18/82"; 4 5 /* 6 * Read in the namelist from the obj file. 7 */ 8 9 #include "defs.h" 10 #include "sym.h" 11 #include "symtab.h" 12 #include "object.h" 13 #include "mappings.h" 14 #include "mappings/filetab.h" 15 #include "mappings/linetab.h" 16 17 #define MAXSYMNO 2000 18 19 char *objname = "obj"; 20 21 LOCAL SYM *sym[MAXSYMNO]; 22 23 readobj(file) 24 char *file; 25 { 26 register FILE *fp; 27 28 if ((fp = fopen(file, "r")) == NIL) { 29 panic("can't open %s", file); 30 } 31 fseek(fp, (long) SIZELOC, 0); 32 objsize = getw(fp); 33 fseek(fp, (long) objsize + 4, 1); 34 if (get(fp, nlhdr) != 1) { 35 panic("readobj: get failed"); 36 } 37 stringtab = alloc(nlhdr.stringsize, char); 38 fread(stringtab, sizeof(char), nlhdr.stringsize, fp); 39 readsyms(fp); 40 readfiles(fp); 41 readlines(fp); 42 fclose(fp); 43 } 44 45 /* 46 * allocate and read in file name information table 47 */ 48 49 LOCAL readfiles(fp) 50 register FILE *fp; 51 { 52 register int i; 53 register FILETAB *ftp; 54 FILETAB temp; 55 ADDRESS prevaddr; 56 57 filetab = alloc(nlhdr.nfiles, FILETAB); 58 ftp = &filetab[0]; 59 prevaddr = 0; 60 for (i = 0; i < nlhdr.nfiles; i++) { 61 fread(&temp, sizeof(FILETAB), 1, fp); 62 if (temp.addr != prevaddr) { 63 ftp++; 64 } 65 *ftp = temp; 66 ftp->filename += (int) stringtab; 67 prevaddr = ftp->addr; 68 } 69 nlhdr.nfiles = (ftp - &filetab[0]) + 1; 70 skimsource(filetab[0].filename); 71 dotpfile = filetab[0].filename; 72 } 73 74 /* 75 * allocate and read in line number information table 76 */ 77 78 LOCAL readlines(fp) 79 FILE *fp; 80 { 81 register LINENO oline; 82 register ADDRESS oaddr; 83 register LINETAB *lp; 84 FILETAB *ftp; 85 short lineincr; 86 87 if (nlhdr.nlines == 0) { 88 return; 89 } 90 linetab = alloc(nlhdr.nlines, LINETAB); 91 for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 92 lp->line = 0; 93 } 94 for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { 95 linetab[ftp->lineindex].line = ftp->line; 96 } 97 oline = 0; 98 oaddr = 0; 99 for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 100 if (lp->line != 0) { 101 oline = lp->line; 102 } 103 lineincr = (unsigned) getc(fp); 104 if (lineincr > 127) { 105 lineincr -= 256; 106 } 107 oline += lineincr; 108 oaddr += (unsigned) getc(fp); 109 lp->line = oline; 110 lp->addr = oaddr; 111 } 112 } 113 114 /* 115 * read in the symbols 116 */ 117 118 readsyms(fp) 119 FILE *fp; 120 { 121 register int i; 122 int symno; 123 124 symtab = st_creat(nlhdr.nsyms); 125 for (i = 0; i < nlhdr.nsyms; i++) { 126 symno = getw(fp); 127 if (symno >= MAXSYMNO) { 128 panic("symbol number too large"); 129 } 130 sym[symno] = readsym(fp); 131 } 132 if (backpatch() != 0) { 133 panic("patchlist not empty after reading namelist"); 134 } 135 if (program == NIL) { 136 panic("no program"); 137 } 138 maketypes(); 139 } 140 141 typedef struct patchinfo { 142 SYM **patchsym; 143 struct patchinfo *next_patch; 144 } PATCH; 145 146 LOCAL PATCH *phead; 147 148 /* 149 * Go through patchlist looking for symbol numbers for which the 150 * sym array now has a non-NIL entry. 151 * 152 * Afterwards, zap the sym array. 153 */ 154 155 int backpatch() 156 { 157 register PATCH *p, *last, *next; 158 register SYM *s, **t; 159 int count; 160 161 last = NIL; 162 count = 0; 163 for (p = phead; p != NIL; p = next) { 164 next = p->next_patch; 165 t = p->patchsym; 166 if ((s = sym[(int) *t]) != NIL) { 167 *t = s; 168 if (last == NIL) { 169 phead = next; 170 } else { 171 last->next_patch = next; 172 } 173 dispose(p); 174 } else { 175 last = p; 176 count++; 177 } 178 } 179 for (t = &sym[0]; t < &sym[MAXSYMNO]; t++) { 180 *t = NIL; 181 } 182 return(count); 183 } 184 185 /* 186 * Check to see if the given pointer (really symbol number) should 187 * be added to the patch list. The argument is double indirect 188 * to do call by reference passing. 189 */ 190 191 chkpatch(p) 192 SYM **p; 193 { 194 register SYM *s, *t; 195 register PATCH *patch; 196 197 if ((s = *p) != NIL) { 198 if ((t = sym[(int) s]) != NIL) { 199 *p = t; 200 } else { 201 patch = alloc(1, PATCH); 202 patch->patchsym = p; 203 patch->next_patch = phead; 204 phead = patch; 205 } 206 } 207 } 208 209 /* 210 * Free all the object information. 211 */ 212 213 objfree() 214 { 215 register int i; 216 217 st_destroy(symtab); 218 dispose(stringtab); 219 dispose(filetab); 220 dispose(linetab); 221 clrfunctab(); 222 for (i = 0; i < MAXSYMNO; i++) { 223 sym[i] = NIL; 224 } 225 } 226