15500Slinton /* Copyright (c) 1982 Regents of the University of California */ 25500Slinton 3*5569Slinton static char sccsid[] = "@(#)readobj.c 1.2 01/19/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" 13*5569Slinton #include "objfmt.h" 145500Slinton #include "mappings.h" 155500Slinton #include "mappings/filetab.h" 165500Slinton #include "mappings/linetab.h" 175500Slinton 185500Slinton #define MAXSYMNO 2000 195500Slinton 205500Slinton char *objname = "obj"; 215500Slinton 225500Slinton LOCAL SYM *sym[MAXSYMNO]; 235500Slinton 245500Slinton readobj(file) 255500Slinton char *file; 265500Slinton { 275500Slinton register FILE *fp; 28*5569Slinton struct pxhdr hdr; 295500Slinton 305500Slinton if ((fp = fopen(file, "r")) == NIL) { 315500Slinton panic("can't open %s", file); 325500Slinton } 33*5569Slinton fseek(fp, (long) (HEADER_BYTES - sizeof(struct pxhdr)), 0); 34*5569Slinton get(fp, hdr); 35*5569Slinton objsize = hdr.objsize; 36*5569Slinton fseek(fp, (long) objsize, 1); 375500Slinton if (get(fp, nlhdr) != 1) { 385500Slinton panic("readobj: get failed"); 395500Slinton } 405500Slinton stringtab = alloc(nlhdr.stringsize, char); 415500Slinton fread(stringtab, sizeof(char), nlhdr.stringsize, fp); 425500Slinton readsyms(fp); 435500Slinton readfiles(fp); 445500Slinton readlines(fp); 455500Slinton fclose(fp); 465500Slinton } 475500Slinton 485500Slinton /* 495500Slinton * allocate and read in file name information table 505500Slinton */ 515500Slinton 525500Slinton LOCAL readfiles(fp) 535500Slinton register FILE *fp; 545500Slinton { 555500Slinton register int i; 565500Slinton register FILETAB *ftp; 575500Slinton FILETAB temp; 585500Slinton ADDRESS prevaddr; 595500Slinton 605500Slinton filetab = alloc(nlhdr.nfiles, FILETAB); 615500Slinton ftp = &filetab[0]; 625500Slinton prevaddr = 0; 635500Slinton for (i = 0; i < nlhdr.nfiles; i++) { 645500Slinton fread(&temp, sizeof(FILETAB), 1, fp); 655500Slinton if (temp.addr != prevaddr) { 665500Slinton ftp++; 675500Slinton } 685500Slinton *ftp = temp; 695500Slinton ftp->filename += (int) stringtab; 705500Slinton prevaddr = ftp->addr; 715500Slinton } 725500Slinton nlhdr.nfiles = (ftp - &filetab[0]) + 1; 735500Slinton skimsource(filetab[0].filename); 745500Slinton dotpfile = filetab[0].filename; 755500Slinton } 765500Slinton 775500Slinton /* 785500Slinton * allocate and read in line number information table 795500Slinton */ 805500Slinton 815500Slinton LOCAL readlines(fp) 825500Slinton FILE *fp; 835500Slinton { 845500Slinton register LINENO oline; 855500Slinton register ADDRESS oaddr; 865500Slinton register LINETAB *lp; 875500Slinton FILETAB *ftp; 885500Slinton short lineincr; 895500Slinton 905500Slinton if (nlhdr.nlines == 0) { 915500Slinton return; 925500Slinton } 935500Slinton linetab = alloc(nlhdr.nlines, LINETAB); 945500Slinton for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 955500Slinton lp->line = 0; 965500Slinton } 975500Slinton for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { 985500Slinton linetab[ftp->lineindex].line = ftp->line; 995500Slinton } 1005500Slinton oline = 0; 1015500Slinton oaddr = 0; 1025500Slinton for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 1035500Slinton if (lp->line != 0) { 1045500Slinton oline = lp->line; 1055500Slinton } 1065500Slinton lineincr = (unsigned) getc(fp); 1075500Slinton if (lineincr > 127) { 1085500Slinton lineincr -= 256; 1095500Slinton } 1105500Slinton oline += lineincr; 1115500Slinton oaddr += (unsigned) getc(fp); 1125500Slinton lp->line = oline; 1135500Slinton lp->addr = oaddr; 1145500Slinton } 1155500Slinton } 1165500Slinton 1175500Slinton /* 1185500Slinton * read in the symbols 1195500Slinton */ 1205500Slinton 1215500Slinton readsyms(fp) 1225500Slinton FILE *fp; 1235500Slinton { 1245500Slinton register int i; 1255500Slinton int symno; 1265500Slinton 1275500Slinton symtab = st_creat(nlhdr.nsyms); 1285500Slinton for (i = 0; i < nlhdr.nsyms; i++) { 1295500Slinton symno = getw(fp); 1305500Slinton if (symno >= MAXSYMNO) { 1315500Slinton panic("symbol number too large"); 1325500Slinton } 1335500Slinton sym[symno] = readsym(fp); 1345500Slinton } 1355500Slinton if (backpatch() != 0) { 1365500Slinton panic("patchlist not empty after reading namelist"); 1375500Slinton } 1385500Slinton if (program == NIL) { 1395500Slinton panic("no program"); 1405500Slinton } 1415500Slinton maketypes(); 1425500Slinton } 1435500Slinton 1445500Slinton typedef struct patchinfo { 1455500Slinton SYM **patchsym; 1465500Slinton struct patchinfo *next_patch; 1475500Slinton } PATCH; 1485500Slinton 1495500Slinton LOCAL PATCH *phead; 1505500Slinton 1515500Slinton /* 1525500Slinton * Go through patchlist looking for symbol numbers for which the 1535500Slinton * sym array now has a non-NIL entry. 1545500Slinton * 1555500Slinton * Afterwards, zap the sym array. 1565500Slinton */ 1575500Slinton 1585500Slinton int backpatch() 1595500Slinton { 1605500Slinton register PATCH *p, *last, *next; 1615500Slinton register SYM *s, **t; 1625500Slinton int count; 1635500Slinton 1645500Slinton last = NIL; 1655500Slinton count = 0; 1665500Slinton for (p = phead; p != NIL; p = next) { 1675500Slinton next = p->next_patch; 1685500Slinton t = p->patchsym; 1695500Slinton if ((s = sym[(int) *t]) != NIL) { 1705500Slinton *t = s; 1715500Slinton if (last == NIL) { 1725500Slinton phead = next; 1735500Slinton } else { 1745500Slinton last->next_patch = next; 1755500Slinton } 1765500Slinton dispose(p); 1775500Slinton } else { 1785500Slinton last = p; 1795500Slinton count++; 1805500Slinton } 1815500Slinton } 1825500Slinton for (t = &sym[0]; t < &sym[MAXSYMNO]; t++) { 1835500Slinton *t = NIL; 1845500Slinton } 1855500Slinton return(count); 1865500Slinton } 1875500Slinton 1885500Slinton /* 1895500Slinton * Check to see if the given pointer (really symbol number) should 1905500Slinton * be added to the patch list. The argument is double indirect 1915500Slinton * to do call by reference passing. 1925500Slinton */ 1935500Slinton 1945500Slinton chkpatch(p) 1955500Slinton SYM **p; 1965500Slinton { 1975500Slinton register SYM *s, *t; 1985500Slinton register PATCH *patch; 1995500Slinton 2005500Slinton if ((s = *p) != NIL) { 2015500Slinton if ((t = sym[(int) s]) != NIL) { 2025500Slinton *p = t; 2035500Slinton } else { 2045500Slinton patch = alloc(1, PATCH); 2055500Slinton patch->patchsym = p; 2065500Slinton patch->next_patch = phead; 2075500Slinton phead = patch; 2085500Slinton } 2095500Slinton } 2105500Slinton } 2115500Slinton 2125500Slinton /* 2135500Slinton * Free all the object information. 2145500Slinton */ 2155500Slinton 2165500Slinton objfree() 2175500Slinton { 2185500Slinton register int i; 2195500Slinton 2205500Slinton st_destroy(symtab); 2215500Slinton dispose(stringtab); 2225500Slinton dispose(filetab); 2235500Slinton dispose(linetab); 2245500Slinton clrfunctab(); 2255500Slinton for (i = 0; i < MAXSYMNO; i++) { 2265500Slinton sym[i] = NIL; 2275500Slinton } 2285500Slinton } 229