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