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