148097Sbostic /*-
2*62142Sbostic * Copyright (c) 1982, 1993
3*62142Sbostic * The Regents of the University of California. All rights reserved.
448097Sbostic *
548097Sbostic * %sccs.include.redist.c%
622767Smckusick */
75500Slinton
822767Smckusick #ifndef lint
9*62142Sbostic static char sccsid[] = "@(#)readobj.c 8.1 (Berkeley) 06/06/93";
1048097Sbostic #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
readobj(file)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
readfiles(fp)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
readlines(fp)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
readsyms(fp)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
backpatch()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
chkpatch(p)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
objfree()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