15500Slinton /* Copyright (c) 1982 Regents of the University of California */ 25500Slinton 3*5649Slinton static char sccsid[] = "@(#)readobj.c 1.3 02/02/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" 14*5649Slinton #include "main.h" 155500Slinton #include "mappings.h" 165500Slinton #include "mappings/filetab.h" 175500Slinton #include "mappings/linetab.h" 185500Slinton 195500Slinton #define MAXSYMNO 2000 205500Slinton 215500Slinton char *objname = "obj"; 225500Slinton 235500Slinton LOCAL SYM *sym[MAXSYMNO]; 245500Slinton 255500Slinton readobj(file) 265500Slinton char *file; 275500Slinton { 285500Slinton register FILE *fp; 295569Slinton struct pxhdr hdr; 305500Slinton 315500Slinton if ((fp = fopen(file, "r")) == NIL) { 325500Slinton panic("can't open %s", file); 335500Slinton } 345569Slinton get(fp, hdr); 35*5649Slinton if (hdr.magicnum != MAGICNUM) { 36*5649Slinton fseek(fp, (long) (HEADER_BYTES - sizeof(struct pxhdr)), 0); 37*5649Slinton get(fp, hdr); 38*5649Slinton if (hdr.magicnum != MAGICNUM) { 39*5649Slinton fatal("%s is not a Pascal object file", file); 40*5649Slinton } 41*5649Slinton } 42*5649Slinton if (hdr.symtabsize == 0) { 43*5649Slinton fatal("%s doesn't have symbolic information", file); 44*5649Slinton } 455569Slinton objsize = hdr.objsize; 465569Slinton fseek(fp, (long) objsize, 1); 475500Slinton if (get(fp, nlhdr) != 1) { 48*5649Slinton panic("can't read nlhdr"); 495500Slinton } 50*5649Slinton if (option('h')) { 51*5649Slinton printf("\nHeader information:\n"); 52*5649Slinton printf("\tobject size %d\n", objsize); 53*5649Slinton printf("\tsymtab size %d\n", hdr.symtabsize); 54*5649Slinton printf("\tstringsize %d\n", nlhdr.stringsize); 55*5649Slinton printf("\tnsyms %d\n", nlhdr.nsyms); 56*5649Slinton printf("\tnfiles %d\n", nlhdr.nfiles); 57*5649Slinton printf("\tnlines %d\n", nlhdr.nlines); 58*5649Slinton } 595500Slinton stringtab = alloc(nlhdr.stringsize, char); 605500Slinton fread(stringtab, sizeof(char), nlhdr.stringsize, fp); 615500Slinton readsyms(fp); 625500Slinton readfiles(fp); 635500Slinton readlines(fp); 645500Slinton fclose(fp); 655500Slinton } 665500Slinton 675500Slinton /* 685500Slinton * allocate and read in file name information table 695500Slinton */ 705500Slinton 715500Slinton LOCAL readfiles(fp) 725500Slinton register FILE *fp; 735500Slinton { 745500Slinton register int i; 755500Slinton register FILETAB *ftp; 765500Slinton FILETAB temp; 775500Slinton ADDRESS prevaddr; 785500Slinton 795500Slinton filetab = alloc(nlhdr.nfiles, FILETAB); 805500Slinton ftp = &filetab[0]; 815500Slinton prevaddr = 0; 825500Slinton for (i = 0; i < nlhdr.nfiles; i++) { 835500Slinton fread(&temp, sizeof(FILETAB), 1, fp); 845500Slinton if (temp.addr != prevaddr) { 855500Slinton ftp++; 865500Slinton } 875500Slinton *ftp = temp; 885500Slinton ftp->filename += (int) stringtab; 895500Slinton prevaddr = ftp->addr; 905500Slinton } 915500Slinton nlhdr.nfiles = (ftp - &filetab[0]) + 1; 925500Slinton skimsource(filetab[0].filename); 935500Slinton dotpfile = filetab[0].filename; 945500Slinton } 955500Slinton 965500Slinton /* 975500Slinton * allocate and read in line number information table 985500Slinton */ 995500Slinton 1005500Slinton LOCAL readlines(fp) 1015500Slinton FILE *fp; 1025500Slinton { 1035500Slinton register LINENO oline; 1045500Slinton register ADDRESS oaddr; 1055500Slinton register LINETAB *lp; 1065500Slinton FILETAB *ftp; 1075500Slinton short lineincr; 1085500Slinton 1095500Slinton if (nlhdr.nlines == 0) { 1105500Slinton return; 1115500Slinton } 1125500Slinton linetab = alloc(nlhdr.nlines, LINETAB); 1135500Slinton for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 1145500Slinton lp->line = 0; 1155500Slinton } 1165500Slinton for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { 1175500Slinton linetab[ftp->lineindex].line = ftp->line; 1185500Slinton } 1195500Slinton oline = 0; 1205500Slinton oaddr = 0; 1215500Slinton for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 1225500Slinton if (lp->line != 0) { 1235500Slinton oline = lp->line; 1245500Slinton } 1255500Slinton lineincr = (unsigned) getc(fp); 1265500Slinton if (lineincr > 127) { 1275500Slinton lineincr -= 256; 1285500Slinton } 1295500Slinton oline += lineincr; 1305500Slinton oaddr += (unsigned) getc(fp); 1315500Slinton lp->line = oline; 1325500Slinton lp->addr = oaddr; 1335500Slinton } 1345500Slinton } 1355500Slinton 1365500Slinton /* 1375500Slinton * read in the symbols 1385500Slinton */ 1395500Slinton 1405500Slinton readsyms(fp) 1415500Slinton FILE *fp; 1425500Slinton { 1435500Slinton register int i; 1445500Slinton int symno; 1455500Slinton 1465500Slinton symtab = st_creat(nlhdr.nsyms); 1475500Slinton for (i = 0; i < nlhdr.nsyms; i++) { 1485500Slinton symno = getw(fp); 1495500Slinton if (symno >= MAXSYMNO) { 1505500Slinton panic("symbol number too large"); 1515500Slinton } 1525500Slinton sym[symno] = readsym(fp); 1535500Slinton } 1545500Slinton if (backpatch() != 0) { 1555500Slinton panic("patchlist not empty after reading namelist"); 1565500Slinton } 1575500Slinton if (program == NIL) { 1585500Slinton panic("no program"); 1595500Slinton } 1605500Slinton maketypes(); 1615500Slinton } 1625500Slinton 1635500Slinton typedef struct patchinfo { 1645500Slinton SYM **patchsym; 1655500Slinton struct patchinfo *next_patch; 1665500Slinton } PATCH; 1675500Slinton 1685500Slinton LOCAL PATCH *phead; 1695500Slinton 1705500Slinton /* 1715500Slinton * Go through patchlist looking for symbol numbers for which the 1725500Slinton * sym array now has a non-NIL entry. 1735500Slinton * 1745500Slinton * Afterwards, zap the sym array. 1755500Slinton */ 1765500Slinton 1775500Slinton int backpatch() 1785500Slinton { 1795500Slinton register PATCH *p, *last, *next; 1805500Slinton register SYM *s, **t; 1815500Slinton int count; 1825500Slinton 1835500Slinton last = NIL; 1845500Slinton count = 0; 1855500Slinton for (p = phead; p != NIL; p = next) { 1865500Slinton next = p->next_patch; 1875500Slinton t = p->patchsym; 1885500Slinton if ((s = sym[(int) *t]) != NIL) { 1895500Slinton *t = s; 1905500Slinton if (last == NIL) { 1915500Slinton phead = next; 1925500Slinton } else { 1935500Slinton last->next_patch = next; 1945500Slinton } 1955500Slinton dispose(p); 1965500Slinton } else { 1975500Slinton last = p; 1985500Slinton count++; 1995500Slinton } 2005500Slinton } 2015500Slinton for (t = &sym[0]; t < &sym[MAXSYMNO]; t++) { 2025500Slinton *t = NIL; 2035500Slinton } 2045500Slinton return(count); 2055500Slinton } 2065500Slinton 2075500Slinton /* 2085500Slinton * Check to see if the given pointer (really symbol number) should 2095500Slinton * be added to the patch list. The argument is double indirect 2105500Slinton * to do call by reference passing. 2115500Slinton */ 2125500Slinton 2135500Slinton chkpatch(p) 2145500Slinton SYM **p; 2155500Slinton { 2165500Slinton register SYM *s, *t; 2175500Slinton register PATCH *patch; 2185500Slinton 2195500Slinton if ((s = *p) != NIL) { 2205500Slinton if ((t = sym[(int) s]) != NIL) { 2215500Slinton *p = t; 2225500Slinton } else { 2235500Slinton patch = alloc(1, PATCH); 2245500Slinton patch->patchsym = p; 2255500Slinton patch->next_patch = phead; 2265500Slinton phead = patch; 2275500Slinton } 2285500Slinton } 2295500Slinton } 2305500Slinton 2315500Slinton /* 2325500Slinton * Free all the object information. 2335500Slinton */ 2345500Slinton 2355500Slinton objfree() 2365500Slinton { 2375500Slinton register int i; 2385500Slinton 2395500Slinton st_destroy(symtab); 2405500Slinton dispose(stringtab); 2415500Slinton dispose(filetab); 2425500Slinton dispose(linetab); 2435500Slinton clrfunctab(); 2445500Slinton for (i = 0; i < MAXSYMNO; i++) { 2455500Slinton sym[i] = NIL; 2465500Slinton } 2475500Slinton } 248