15500Slinton /* Copyright (c) 1982 Regents of the University of California */ 25500Slinton 3*5741Slinton static char sccsid[] = "@(#)readobj.c 1.4 02/10/82"; 45500Slinton 55500Slinton /* 65500Slinton * Read in the namelist from the obj file. 75500Slinton */ 85500Slinton 95500Slinton #include "defs.h" 105500Slinton #include "sym.h" 115500Slinton #include "symtab.h" 125500Slinton #include "object.h" 135569Slinton #include "objfmt.h" 145649Slinton #include "main.h" 155500Slinton #include "mappings.h" 165500Slinton #include "mappings/filetab.h" 175500Slinton #include "mappings/linetab.h" 18*5741Slinton #include "objsym.rep" 195500Slinton 205500Slinton #define MAXSYMNO 2000 215500Slinton 225500Slinton char *objname = "obj"; 235500Slinton 245500Slinton LOCAL SYM *sym[MAXSYMNO]; 255500Slinton 265500Slinton readobj(file) 275500Slinton char *file; 285500Slinton { 29*5741Slinton register FILE *fp; 30*5741Slinton struct pxhdr hdr; 315500Slinton 32*5741Slinton if ((fp = fopen(file, "r")) == NIL) { 33*5741Slinton panic("can't open %s", file); 34*5741Slinton } 35*5741Slinton get(fp, hdr); 36*5741Slinton if (hdr.magicnum != MAGICNUM) { 37*5741Slinton fseek(fp, (long) (HEADER_BYTES - sizeof(struct pxhdr)), 0); 385569Slinton get(fp, hdr); 395649Slinton if (hdr.magicnum != MAGICNUM) { 40*5741Slinton fatal("%s is not a Pascal object file", file); 415649Slinton } 42*5741Slinton } 43*5741Slinton if (hdr.symtabsize == 0) { 44*5741Slinton fatal("%s doesn't have symbolic information", file); 45*5741Slinton } 46*5741Slinton objsize = hdr.objsize; 47*5741Slinton fseek(fp, (long) objsize, 1); 48*5741Slinton if (get(fp, nlhdr) != 1) { 49*5741Slinton panic("can't read nlhdr"); 50*5741Slinton } 51*5741Slinton if (option('h')) { 52*5741Slinton printf("\nHeader information:\n"); 53*5741Slinton printf("\tobject size %d\n", objsize); 54*5741Slinton printf("\tsymtab size %d\n", hdr.symtabsize); 55*5741Slinton printf("\tstringsize %d\n", nlhdr.stringsize); 56*5741Slinton printf("\tnsyms %d\n", nlhdr.nsyms); 57*5741Slinton printf("\tnfiles %d\n", nlhdr.nfiles); 58*5741Slinton printf("\tnlines %d\n", nlhdr.nlines); 59*5741Slinton } 60*5741Slinton stringtab = alloc(nlhdr.stringsize, char); 61*5741Slinton fread(stringtab, sizeof(char), nlhdr.stringsize, fp); 62*5741Slinton readsyms(fp); 63*5741Slinton readfiles(fp); 64*5741Slinton readlines(fp); 65*5741Slinton fclose(fp); 665500Slinton } 675500Slinton 685500Slinton /* 695500Slinton * allocate and read in file name information table 705500Slinton */ 715500Slinton 725500Slinton LOCAL readfiles(fp) 735500Slinton register FILE *fp; 745500Slinton { 75*5741Slinton register int i; 76*5741Slinton register FILETAB *ftp; 77*5741Slinton FILETAB temp; 78*5741Slinton ADDRESS prevaddr; 795500Slinton 80*5741Slinton filetab = alloc(nlhdr.nfiles, FILETAB); 81*5741Slinton ftp = &filetab[0]; 82*5741Slinton prevaddr = 0; 83*5741Slinton for (i = 0; i < nlhdr.nfiles; i++) { 84*5741Slinton fread(&temp, sizeof(FILETAB), 1, fp); 85*5741Slinton if (temp.addr != prevaddr) { 86*5741Slinton ftp++; 875500Slinton } 88*5741Slinton *ftp = temp; 89*5741Slinton ftp->filename += (int) stringtab; 90*5741Slinton prevaddr = ftp->addr; 91*5741Slinton } 92*5741Slinton nlhdr.nfiles = (ftp - &filetab[0]) + 1; 93*5741Slinton skimsource(filetab[0].filename); 94*5741Slinton dotpfile = filetab[0].filename; 955500Slinton } 965500Slinton 975500Slinton /* 985500Slinton * allocate and read in line number information table 995500Slinton */ 1005500Slinton 1015500Slinton LOCAL readlines(fp) 1025500Slinton FILE *fp; 1035500Slinton { 104*5741Slinton register LINENO oline; 105*5741Slinton register ADDRESS oaddr; 106*5741Slinton register LINETAB *lp; 107*5741Slinton FILETAB *ftp; 108*5741Slinton OBJLINE info; 1095500Slinton 110*5741Slinton if (nlhdr.nlines == 0) { 111*5741Slinton return; 112*5741Slinton } 113*5741Slinton linetab = alloc(nlhdr.nlines, LINETAB); 114*5741Slinton for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 115*5741Slinton lp->line = 0; 116*5741Slinton } 117*5741Slinton for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { 118*5741Slinton linetab[ftp->lineindex].line = ftp->line; 119*5741Slinton } 120*5741Slinton oline = 0; 121*5741Slinton oaddr = 0; 122*5741Slinton for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 123*5741Slinton if (lp->line != 0) { 124*5741Slinton oline = lp->line; 1255500Slinton } 126*5741Slinton info.together = getw(fp); 127*5741Slinton oline += info.separate.lineincr; 128*5741Slinton oaddr += info.separate.addrincr; 129*5741Slinton lp->line = oline; 130*5741Slinton lp->addr = oaddr; 131*5741Slinton } 1325500Slinton } 1335500Slinton 1345500Slinton /* 1355500Slinton * read in the symbols 1365500Slinton */ 1375500Slinton 1385500Slinton readsyms(fp) 1395500Slinton FILE *fp; 1405500Slinton { 141*5741Slinton register int i; 142*5741Slinton int symno; 1435500Slinton 144*5741Slinton symtab = st_creat(nlhdr.nsyms); 145*5741Slinton for (i = 0; i < nlhdr.nsyms; i++) { 146*5741Slinton symno = getw(fp); 147*5741Slinton if (symno >= MAXSYMNO) { 148*5741Slinton panic("symbol number too large"); 1495500Slinton } 150*5741Slinton sym[symno] = readsym(fp); 151*5741Slinton } 152*5741Slinton if (backpatch() != 0) { 153*5741Slinton panic("patchlist not empty after reading namelist"); 154*5741Slinton } 155*5741Slinton if (program == NIL) { 156*5741Slinton panic("no program"); 157*5741Slinton } 158*5741Slinton maketypes(); 1595500Slinton } 1605500Slinton 1615500Slinton typedef struct patchinfo { 162*5741Slinton SYM **patchsym; 163*5741Slinton struct patchinfo *next_patch; 1645500Slinton } PATCH; 1655500Slinton 1665500Slinton LOCAL PATCH *phead; 1675500Slinton 1685500Slinton /* 1695500Slinton * Go through patchlist looking for symbol numbers for which the 1705500Slinton * sym array now has a non-NIL entry. 1715500Slinton * 1725500Slinton * Afterwards, zap the sym array. 1735500Slinton */ 1745500Slinton 1755500Slinton int backpatch() 1765500Slinton { 177*5741Slinton register PATCH *p, *last, *next; 178*5741Slinton register SYM *s, **t; 179*5741Slinton int count; 1805500Slinton 181*5741Slinton last = NIL; 182*5741Slinton count = 0; 183*5741Slinton for (p = phead; p != NIL; p = next) { 184*5741Slinton next = p->next_patch; 185*5741Slinton t = p->patchsym; 186*5741Slinton if ((s = sym[(int) *t]) != NIL) { 187*5741Slinton *t = s; 188*5741Slinton if (last == NIL) { 189*5741Slinton phead = next; 190*5741Slinton } else { 191*5741Slinton last->next_patch = next; 192*5741Slinton } 193*5741Slinton dispose(p); 194*5741Slinton } else { 195*5741Slinton last = p; 196*5741Slinton count++; 1975500Slinton } 198*5741Slinton } 199*5741Slinton for (t = &sym[0]; t < &sym[MAXSYMNO]; t++) { 200*5741Slinton *t = NIL; 201*5741Slinton } 202*5741Slinton return(count); 2035500Slinton } 2045500Slinton 2055500Slinton /* 2065500Slinton * Check to see if the given pointer (really symbol number) should 2075500Slinton * be added to the patch list. The argument is double indirect 2085500Slinton * to do call by reference passing. 2095500Slinton */ 2105500Slinton 2115500Slinton chkpatch(p) 2125500Slinton SYM **p; 2135500Slinton { 214*5741Slinton register SYM *s, *t; 215*5741Slinton register PATCH *patch; 2165500Slinton 217*5741Slinton if ((s = *p) != NIL) { 218*5741Slinton if ((t = sym[(int) s]) != NIL) { 219*5741Slinton *p = t; 220*5741Slinton } else { 221*5741Slinton patch = alloc(1, PATCH); 222*5741Slinton patch->patchsym = p; 223*5741Slinton patch->next_patch = phead; 224*5741Slinton phead = patch; 2255500Slinton } 226*5741Slinton } 2275500Slinton } 2285500Slinton 2295500Slinton /* 2305500Slinton * Free all the object information. 2315500Slinton */ 2325500Slinton 2335500Slinton objfree() 2345500Slinton { 235*5741Slinton register int i; 2365500Slinton 237*5741Slinton st_destroy(symtab); 238*5741Slinton dispose(stringtab); 239*5741Slinton dispose(filetab); 240*5741Slinton dispose(linetab); 241*5741Slinton clrfunctab(); 242*5741Slinton for (i = 0; i < MAXSYMNO; i++) { 243*5741Slinton sym[i] = NIL; 244*5741Slinton } 2455500Slinton } 246