15500Slinton /* Copyright (c) 1982 Regents of the University of California */ 25500Slinton 3*6871Slinton static char sccsid[] = "@(#)readobj.c 1.5 05/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" 135569Slinton #include "objfmt.h" 145649Slinton #include "main.h" 155500Slinton #include "mappings.h" 165500Slinton #include "mappings/filetab.h" 175500Slinton #include "mappings/linetab.h" 185741Slinton #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 { 295741Slinton register FILE *fp; 305741Slinton struct pxhdr hdr; 315500Slinton 325741Slinton if ((fp = fopen(file, "r")) == NIL) { 335741Slinton panic("can't open %s", file); 345741Slinton } 355741Slinton get(fp, hdr); 365741Slinton if (hdr.magicnum != MAGICNUM) { 375741Slinton fseek(fp, (long) (HEADER_BYTES - sizeof(struct pxhdr)), 0); 385569Slinton get(fp, hdr); 395649Slinton if (hdr.magicnum != MAGICNUM) { 405741Slinton fatal("%s is not a Pascal object file", file); 415649Slinton } 425741Slinton } 435741Slinton if (hdr.symtabsize == 0) { 445741Slinton fatal("%s doesn't have symbolic information", file); 455741Slinton } 465741Slinton objsize = hdr.objsize; 475741Slinton fseek(fp, (long) objsize, 1); 485741Slinton if (get(fp, nlhdr) != 1) { 495741Slinton panic("can't read nlhdr"); 505741Slinton } 515741Slinton if (option('h')) { 525741Slinton printf("\nHeader information:\n"); 535741Slinton printf("\tobject size %d\n", objsize); 545741Slinton printf("\tsymtab size %d\n", hdr.symtabsize); 555741Slinton printf("\tstringsize %d\n", nlhdr.stringsize); 565741Slinton printf("\tnsyms %d\n", nlhdr.nsyms); 575741Slinton printf("\tnfiles %d\n", nlhdr.nfiles); 585741Slinton printf("\tnlines %d\n", nlhdr.nlines); 595741Slinton } 605741Slinton stringtab = alloc(nlhdr.stringsize, char); 615741Slinton fread(stringtab, sizeof(char), nlhdr.stringsize, fp); 625741Slinton readsyms(fp); 635741Slinton readfiles(fp); 645741Slinton readlines(fp); 655741Slinton fclose(fp); 665500Slinton } 675500Slinton 685500Slinton /* 69*6871Slinton * Allocate and read in file name information table. 705500Slinton */ 715500Slinton 725500Slinton LOCAL readfiles(fp) 735500Slinton register FILE *fp; 745500Slinton { 755741Slinton register int i; 765741Slinton register FILETAB *ftp; 775741Slinton FILETAB temp; 785741Slinton ADDRESS prevaddr; 795500Slinton 805741Slinton filetab = alloc(nlhdr.nfiles, FILETAB); 815741Slinton ftp = &filetab[0]; 825741Slinton prevaddr = 0; 835741Slinton for (i = 0; i < nlhdr.nfiles; i++) { 845741Slinton fread(&temp, sizeof(FILETAB), 1, fp); 855741Slinton if (temp.addr != prevaddr) { 865741Slinton ftp++; 875500Slinton } 885741Slinton *ftp = temp; 895741Slinton ftp->filename += (int) stringtab; 905741Slinton prevaddr = ftp->addr; 915741Slinton } 925741Slinton nlhdr.nfiles = (ftp - &filetab[0]) + 1; 935741Slinton skimsource(filetab[0].filename); 945741Slinton dotpfile = filetab[0].filename; 955500Slinton } 965500Slinton 975500Slinton /* 98*6871Slinton * Allocate and read in line number information table. 995500Slinton */ 1005500Slinton 1015500Slinton LOCAL readlines(fp) 1025500Slinton FILE *fp; 1035500Slinton { 1045741Slinton register LINENO oline; 1055741Slinton register ADDRESS oaddr; 1065741Slinton register LINETAB *lp; 1075741Slinton FILETAB *ftp; 1085741Slinton OBJLINE info; 1095500Slinton 1105741Slinton if (nlhdr.nlines == 0) { 1115741Slinton return; 1125741Slinton } 1135741Slinton linetab = alloc(nlhdr.nlines, LINETAB); 1145741Slinton for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 1155741Slinton lp->line = 0; 1165741Slinton } 1175741Slinton for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { 118*6871Slinton if (ftp->lineindex < nlhdr.nlines) { 119*6871Slinton linetab[ftp->lineindex].line = ftp->line; 120*6871Slinton } 1215741Slinton } 1225741Slinton oline = 0; 1235741Slinton oaddr = 0; 1245741Slinton for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 1255741Slinton if (lp->line != 0) { 1265741Slinton oline = lp->line; 1275500Slinton } 1285741Slinton info.together = getw(fp); 1295741Slinton oline += info.separate.lineincr; 1305741Slinton oaddr += info.separate.addrincr; 1315741Slinton lp->line = oline; 1325741Slinton lp->addr = oaddr; 1335741Slinton } 1345500Slinton } 1355500Slinton 1365500Slinton /* 137*6871Slinton * Read in the symbols. 1385500Slinton */ 1395500Slinton 1405500Slinton readsyms(fp) 1415500Slinton FILE *fp; 1425500Slinton { 1435741Slinton register int i; 1445741Slinton int symno; 1455500Slinton 1465741Slinton symtab = st_creat(nlhdr.nsyms); 1475741Slinton for (i = 0; i < nlhdr.nsyms; i++) { 1485741Slinton symno = getw(fp); 1495741Slinton if (symno >= MAXSYMNO) { 1505741Slinton panic("symbol number too large"); 1515500Slinton } 1525741Slinton sym[symno] = readsym(fp); 1535741Slinton } 1545741Slinton if (backpatch() != 0) { 1555741Slinton panic("patchlist not empty after reading namelist"); 1565741Slinton } 1575741Slinton if (program == NIL) { 1585741Slinton panic("no program"); 1595741Slinton } 1605741Slinton maketypes(); 1615500Slinton } 1625500Slinton 1635500Slinton typedef struct patchinfo { 1645741Slinton SYM **patchsym; 1655741Slinton 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 { 1795741Slinton register PATCH *p, *last, *next; 1805741Slinton register SYM *s, **t; 1815741Slinton int count; 1825500Slinton 1835741Slinton last = NIL; 1845741Slinton count = 0; 1855741Slinton for (p = phead; p != NIL; p = next) { 1865741Slinton next = p->next_patch; 1875741Slinton t = p->patchsym; 1885741Slinton if ((s = sym[(int) *t]) != NIL) { 1895741Slinton *t = s; 1905741Slinton if (last == NIL) { 1915741Slinton phead = next; 1925741Slinton } else { 1935741Slinton last->next_patch = next; 1945741Slinton } 1955741Slinton dispose(p); 1965741Slinton } else { 1975741Slinton last = p; 1985741Slinton count++; 1995500Slinton } 2005741Slinton } 2015741Slinton for (t = &sym[0]; t < &sym[MAXSYMNO]; t++) { 2025741Slinton *t = NIL; 2035741Slinton } 2045741Slinton 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 { 2165741Slinton register SYM *s, *t; 2175741Slinton register PATCH *patch; 2185500Slinton 2195741Slinton if ((s = *p) != NIL) { 2205741Slinton if ((t = sym[(int) s]) != NIL) { 2215741Slinton *p = t; 2225741Slinton } else { 2235741Slinton patch = alloc(1, PATCH); 2245741Slinton patch->patchsym = p; 2255741Slinton patch->next_patch = phead; 2265741Slinton phead = patch; 2275500Slinton } 2285741Slinton } 2295500Slinton } 2305500Slinton 2315500Slinton /* 2325500Slinton * Free all the object information. 2335500Slinton */ 2345500Slinton 2355500Slinton objfree() 2365500Slinton { 2375741Slinton register int i; 2385500Slinton 2395741Slinton st_destroy(symtab); 2405741Slinton dispose(stringtab); 2415741Slinton dispose(filetab); 2425741Slinton dispose(linetab); 2435741Slinton clrfunctab(); 2445741Slinton for (i = 0; i < MAXSYMNO; i++) { 2455741Slinton sym[i] = NIL; 2465741Slinton } 2475500Slinton } 248