1*48097Sbostic /*- 2*48097Sbostic * Copyright (c) 1982 The Regents of the University of California. 3*48097Sbostic * All rights reserved. 4*48097Sbostic * 5*48097Sbostic * %sccs.include.redist.c% 622767Smckusick */ 75500Slinton 822767Smckusick #ifndef lint 9*48097Sbostic static char sccsid[] = "@(#)readobj.c 5.2 (Berkeley) 04/16/91"; 10*48097Sbostic #endif /* not lint */ 115500Slinton 125500Slinton /* 135500Slinton * Read in the namelist from the obj file. 145500Slinton */ 155500Slinton 165500Slinton #include "defs.h" 175500Slinton #include "sym.h" 185500Slinton #include "symtab.h" 195500Slinton #include "object.h" 205569Slinton #include "objfmt.h" 215649Slinton #include "main.h" 225500Slinton #include "mappings.h" 235500Slinton #include "mappings/filetab.h" 245500Slinton #include "mappings/linetab.h" 255741Slinton #include "objsym.rep" 265500Slinton 2711715Slinton #define MAXSYMNO 6000 285500Slinton 295500Slinton char *objname = "obj"; 305500Slinton 315500Slinton LOCAL SYM *sym[MAXSYMNO]; 325500Slinton 335500Slinton readobj(file) 345500Slinton char *file; 355500Slinton { 365741Slinton register FILE *fp; 375741Slinton struct pxhdr hdr; 385500Slinton 395741Slinton if ((fp = fopen(file, "r")) == NIL) { 405741Slinton panic("can't open %s", file); 415741Slinton } 425741Slinton get(fp, hdr); 435741Slinton if (hdr.magicnum != MAGICNUM) { 445741Slinton fseek(fp, (long) (HEADER_BYTES - sizeof(struct pxhdr)), 0); 455569Slinton get(fp, hdr); 465649Slinton if (hdr.magicnum != MAGICNUM) { 475741Slinton fatal("%s is not a Pascal object file", file); 485649Slinton } 495741Slinton } 505741Slinton if (hdr.symtabsize == 0) { 515741Slinton fatal("%s doesn't have symbolic information", file); 525741Slinton } 535741Slinton objsize = hdr.objsize; 545741Slinton fseek(fp, (long) objsize, 1); 555741Slinton if (get(fp, nlhdr) != 1) { 565741Slinton panic("can't read nlhdr"); 575741Slinton } 585741Slinton if (option('h')) { 595741Slinton printf("\nHeader information:\n"); 605741Slinton printf("\tobject size %d\n", objsize); 615741Slinton printf("\tsymtab size %d\n", hdr.symtabsize); 625741Slinton printf("\tstringsize %d\n", nlhdr.stringsize); 635741Slinton printf("\tnsyms %d\n", nlhdr.nsyms); 645741Slinton printf("\tnfiles %d\n", nlhdr.nfiles); 655741Slinton printf("\tnlines %d\n", nlhdr.nlines); 665741Slinton } 675741Slinton stringtab = alloc(nlhdr.stringsize, char); 685741Slinton fread(stringtab, sizeof(char), nlhdr.stringsize, fp); 695741Slinton readsyms(fp); 705741Slinton readfiles(fp); 715741Slinton readlines(fp); 725741Slinton fclose(fp); 735500Slinton } 745500Slinton 755500Slinton /* 766871Slinton * Allocate and read in file name information table. 775500Slinton */ 785500Slinton 795500Slinton LOCAL readfiles(fp) 805500Slinton register FILE *fp; 815500Slinton { 825741Slinton register int i; 835741Slinton register FILETAB *ftp; 845741Slinton FILETAB temp; 855741Slinton ADDRESS prevaddr; 865500Slinton 875741Slinton filetab = alloc(nlhdr.nfiles, FILETAB); 885741Slinton ftp = &filetab[0]; 895741Slinton prevaddr = 0; 905741Slinton for (i = 0; i < nlhdr.nfiles; i++) { 915741Slinton fread(&temp, sizeof(FILETAB), 1, fp); 925741Slinton if (temp.addr != prevaddr) { 935741Slinton ftp++; 945500Slinton } 955741Slinton *ftp = temp; 965741Slinton ftp->filename += (int) stringtab; 975741Slinton prevaddr = ftp->addr; 985741Slinton } 995741Slinton nlhdr.nfiles = (ftp - &filetab[0]) + 1; 1005741Slinton skimsource(filetab[0].filename); 1015741Slinton dotpfile = filetab[0].filename; 1025500Slinton } 1035500Slinton 1045500Slinton /* 1056871Slinton * Allocate and read in line number information table. 1065500Slinton */ 1075500Slinton 1085500Slinton LOCAL readlines(fp) 1095500Slinton FILE *fp; 1105500Slinton { 1115741Slinton register LINENO oline; 1125741Slinton register ADDRESS oaddr; 1135741Slinton register LINETAB *lp; 1145741Slinton FILETAB *ftp; 1155741Slinton OBJLINE info; 1165500Slinton 1175741Slinton if (nlhdr.nlines == 0) { 1185741Slinton return; 1195741Slinton } 1205741Slinton linetab = alloc(nlhdr.nlines, LINETAB); 1215741Slinton for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 1225741Slinton lp->line = 0; 1235741Slinton } 1245741Slinton for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { 1256871Slinton if (ftp->lineindex < nlhdr.nlines) { 1266871Slinton linetab[ftp->lineindex].line = ftp->line; 1276871Slinton } 1285741Slinton } 1295741Slinton oline = 0; 1305741Slinton oaddr = 0; 1315741Slinton for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) { 1325741Slinton if (lp->line != 0) { 1335741Slinton oline = lp->line; 1345500Slinton } 1355741Slinton info.together = getw(fp); 1365741Slinton oline += info.separate.lineincr; 1375741Slinton oaddr += info.separate.addrincr; 1385741Slinton lp->line = oline; 1395741Slinton lp->addr = oaddr; 1405741Slinton } 1415500Slinton } 1425500Slinton 1435500Slinton /* 1446871Slinton * Read in the symbols. 1455500Slinton */ 1465500Slinton 1475500Slinton readsyms(fp) 1485500Slinton FILE *fp; 1495500Slinton { 1505741Slinton register int i; 1515741Slinton int symno; 1525500Slinton 1535741Slinton symtab = st_creat(nlhdr.nsyms); 1545741Slinton for (i = 0; i < nlhdr.nsyms; i++) { 1555741Slinton symno = getw(fp); 1565741Slinton if (symno >= MAXSYMNO) { 15711715Slinton panic("symbol number too large (%d)", symno); 1585500Slinton } 1595741Slinton sym[symno] = readsym(fp); 1605741Slinton } 1615741Slinton if (backpatch() != 0) { 1625741Slinton panic("patchlist not empty after reading namelist"); 1635741Slinton } 1645741Slinton if (program == NIL) { 1655741Slinton panic("no program"); 1665741Slinton } 1675741Slinton maketypes(); 1685500Slinton } 1695500Slinton 1705500Slinton typedef struct patchinfo { 1715741Slinton SYM **patchsym; 1725741Slinton struct patchinfo *next_patch; 1735500Slinton } PATCH; 1745500Slinton 1755500Slinton LOCAL PATCH *phead; 1765500Slinton 1775500Slinton /* 1785500Slinton * Go through patchlist looking for symbol numbers for which the 1795500Slinton * sym array now has a non-NIL entry. 1805500Slinton * 1815500Slinton * Afterwards, zap the sym array. 1825500Slinton */ 1835500Slinton 1845500Slinton int backpatch() 1855500Slinton { 1865741Slinton register PATCH *p, *last, *next; 1875741Slinton register SYM *s, **t; 1885741Slinton int count; 1895500Slinton 1905741Slinton last = NIL; 1915741Slinton count = 0; 1925741Slinton for (p = phead; p != NIL; p = next) { 1935741Slinton next = p->next_patch; 1945741Slinton t = p->patchsym; 1955741Slinton if ((s = sym[(int) *t]) != NIL) { 1965741Slinton *t = s; 1975741Slinton if (last == NIL) { 1985741Slinton phead = next; 1995741Slinton } else { 2005741Slinton last->next_patch = next; 2015741Slinton } 2025741Slinton dispose(p); 2035741Slinton } else { 2045741Slinton last = p; 2055741Slinton count++; 2065500Slinton } 2075741Slinton } 2085741Slinton for (t = &sym[0]; t < &sym[MAXSYMNO]; t++) { 2095741Slinton *t = NIL; 2105741Slinton } 2115741Slinton return(count); 2125500Slinton } 2135500Slinton 2145500Slinton /* 2155500Slinton * Check to see if the given pointer (really symbol number) should 2165500Slinton * be added to the patch list. The argument is double indirect 2175500Slinton * to do call by reference passing. 2185500Slinton */ 2195500Slinton 2205500Slinton chkpatch(p) 2215500Slinton SYM **p; 2225500Slinton { 2235741Slinton register SYM *s, *t; 2245741Slinton register PATCH *patch; 2255500Slinton 2265741Slinton if ((s = *p) != NIL) { 2275741Slinton if ((t = sym[(int) s]) != NIL) { 2285741Slinton *p = t; 2295741Slinton } else { 2305741Slinton patch = alloc(1, PATCH); 2315741Slinton patch->patchsym = p; 2325741Slinton patch->next_patch = phead; 2335741Slinton phead = patch; 2345500Slinton } 2355741Slinton } 2365500Slinton } 2375500Slinton 2385500Slinton /* 2395500Slinton * Free all the object information. 2405500Slinton */ 2415500Slinton 2425500Slinton objfree() 2435500Slinton { 2445741Slinton register int i; 2455500Slinton 2465741Slinton st_destroy(symtab); 2475741Slinton dispose(stringtab); 2485741Slinton dispose(filetab); 2495741Slinton dispose(linetab); 2505741Slinton clrfunctab(); 2515741Slinton for (i = 0; i < MAXSYMNO; i++) { 2525741Slinton sym[i] = NIL; 2535741Slinton } 2545500Slinton } 255