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