1: /*
2: * Copyright (c) 1982 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)readobj.c 5.1 (Berkeley) 6/7/85";
9: #endif not lint
10:
11: /*
12: * Read in the namelist from the obj file.
13: */
14:
15: #include "defs.h"
16: #include "sym.h"
17: #include "symtab.h"
18: #include "object.h"
19: #include "objfmt.h"
20: #include "main.h"
21: #include "mappings.h"
22: #include "mappings/filetab.h"
23: #include "mappings/linetab.h"
24: #include "objsym.rep"
25:
26: #define MAXSYMNO 6000
27:
28: char *objname = "obj";
29:
30: LOCAL SYM *sym[MAXSYMNO];
31:
32: readobj(file)
33: char *file;
34: {
35: register FILE *fp;
36: struct pxhdr hdr;
37:
38: if ((fp = fopen(file, "r")) == NIL) {
39: panic("can't open %s", file);
40: }
41: get(fp, hdr);
42: if (hdr.magicnum != MAGICNUM) {
43: fseek(fp, (long) (HEADER_BYTES - sizeof(struct pxhdr)), 0);
44: get(fp, hdr);
45: if (hdr.magicnum != MAGICNUM) {
46: fatal("%s is not a Pascal object file", file);
47: }
48: }
49: if (hdr.symtabsize == 0) {
50: fatal("%s doesn't have symbolic information", file);
51: }
52: objsize = hdr.objsize;
53: fseek(fp, (long) objsize, 1);
54: if (get(fp, nlhdr) != 1) {
55: panic("can't read nlhdr");
56: }
57: if (option('h')) {
58: printf("\nHeader information:\n");
59: printf("\tobject size %d\n", objsize);
60: printf("\tsymtab size %d\n", hdr.symtabsize);
61: printf("\tstringsize %d\n", nlhdr.stringsize);
62: printf("\tnsyms %d\n", nlhdr.nsyms);
63: printf("\tnfiles %d\n", nlhdr.nfiles);
64: printf("\tnlines %d\n", nlhdr.nlines);
65: }
66: stringtab = alloc(nlhdr.stringsize, char);
67: fread(stringtab, sizeof(char), nlhdr.stringsize, fp);
68: readsyms(fp);
69: readfiles(fp);
70: readlines(fp);
71: fclose(fp);
72: }
73:
74: /*
75: * Allocate and read in file name information table.
76: */
77:
78: LOCAL readfiles(fp)
79: register FILE *fp;
80: {
81: register int i;
82: register FILETAB *ftp;
83: FILETAB temp;
84: ADDRESS prevaddr;
85:
86: filetab = alloc(nlhdr.nfiles, FILETAB);
87: ftp = &filetab[0];
88: prevaddr = 0;
89: for (i = 0; i < nlhdr.nfiles; i++) {
90: fread(&temp, sizeof(FILETAB), 1, fp);
91: if (temp.addr != prevaddr) {
92: ftp++;
93: }
94: *ftp = temp;
95: ftp->filename += (int) stringtab;
96: prevaddr = ftp->addr;
97: }
98: nlhdr.nfiles = (ftp - &filetab[0]) + 1;
99: skimsource(filetab[0].filename);
100: dotpfile = filetab[0].filename;
101: }
102:
103: /*
104: * Allocate and read in line number information table.
105: */
106:
107: LOCAL readlines(fp)
108: FILE *fp;
109: {
110: register LINENO oline;
111: register ADDRESS oaddr;
112: register LINETAB *lp;
113: FILETAB *ftp;
114: OBJLINE info;
115:
116: if (nlhdr.nlines == 0) {
117: return;
118: }
119: linetab = alloc(nlhdr.nlines, LINETAB);
120: for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) {
121: lp->line = 0;
122: }
123: for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) {
124: if (ftp->lineindex < nlhdr.nlines) {
125: linetab[ftp->lineindex].line = ftp->line;
126: }
127: }
128: oline = 0;
129: oaddr = 0;
130: for (lp = &linetab[0]; lp < &linetab[nlhdr.nlines]; lp++) {
131: if (lp->line != 0) {
132: oline = lp->line;
133: }
134: info.together = getw(fp);
135: oline += info.separate.lineincr;
136: oaddr += info.separate.addrincr;
137: lp->line = oline;
138: lp->addr = oaddr;
139: }
140: }
141:
142: /*
143: * Read in the symbols.
144: */
145:
146: readsyms(fp)
147: FILE *fp;
148: {
149: register int i;
150: int symno;
151:
152: symtab = st_creat(nlhdr.nsyms);
153: for (i = 0; i < nlhdr.nsyms; i++) {
154: symno = getw(fp);
155: if (symno >= MAXSYMNO) {
156: panic("symbol number too large (%d)", symno);
157: }
158: sym[symno] = readsym(fp);
159: }
160: if (backpatch() != 0) {
161: panic("patchlist not empty after reading namelist");
162: }
163: if (program == NIL) {
164: panic("no program");
165: }
166: maketypes();
167: }
168:
169: typedef struct patchinfo {
170: SYM **patchsym;
171: struct patchinfo *next_patch;
172: } PATCH;
173:
174: LOCAL PATCH *phead;
175:
176: /*
177: * Go through patchlist looking for symbol numbers for which the
178: * sym array now has a non-NIL entry.
179: *
180: * Afterwards, zap the sym array.
181: */
182:
183: int backpatch()
184: {
185: register PATCH *p, *last, *next;
186: register SYM *s, **t;
187: int count;
188:
189: last = NIL;
190: count = 0;
191: for (p = phead; p != NIL; p = next) {
192: next = p->next_patch;
193: t = p->patchsym;
194: if ((s = sym[(int) *t]) != NIL) {
195: *t = s;
196: if (last == NIL) {
197: phead = next;
198: } else {
199: last->next_patch = next;
200: }
201: dispose(p);
202: } else {
203: last = p;
204: count++;
205: }
206: }
207: for (t = &sym[0]; t < &sym[MAXSYMNO]; t++) {
208: *t = NIL;
209: }
210: return(count);
211: }
212:
213: /*
214: * Check to see if the given pointer (really symbol number) should
215: * be added to the patch list. The argument is double indirect
216: * to do call by reference passing.
217: */
218:
219: chkpatch(p)
220: SYM **p;
221: {
222: register SYM *s, *t;
223: register PATCH *patch;
224:
225: if ((s = *p) != NIL) {
226: if ((t = sym[(int) s]) != NIL) {
227: *p = t;
228: } else {
229: patch = alloc(1, PATCH);
230: patch->patchsym = p;
231: patch->next_patch = phead;
232: phead = patch;
233: }
234: }
235: }
236:
237: /*
238: * Free all the object information.
239: */
240:
241: objfree()
242: {
243: register int i;
244:
245: st_destroy(symtab);
246: dispose(stringtab);
247: dispose(filetab);
248: dispose(linetab);
249: clrfunctab();
250: for (i = 0; i < MAXSYMNO; i++) {
251: sym[i] = NIL;
252: }
253: }
Defined functions
Defined variables
sccsid
defined in line
8;
never used
Defined struct's
Defined typedef's
Defined macros