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