|
|
1.1 root 1: /*
2: * Copyright (c) 1980 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[] = "@(#)savenl.c 5.1 (Berkeley) 6/5/85";
9: #endif not lint
10:
11: /*
12: * savenl - routines for saving namelist and line number information
13: *
14: * This module contains the routines that make pi dump a namelist
15: * at the end of the object file. We do this by first creating
16: * four temporary files in "startnlfile". One temp file contains
17: * the string table, one the symbol table, one the file name
18: * information and one the line number information.
19: *
20: * Prior to generation of the code for a statement the "lineno"
21: * routine is called to dump the line number and current object
22: * address. At the end of each block "savenl" is called to dump
23: * the strings and symbol structures.
24: *
25: * At the end of execution "copynlfile" is called and it copies
26: * the temp files onto the end of the obj file.
27: *
28: * In case of error, "removenlfile" is called to destroy the temp files.
29: *
30: * The only other changes to pi are in calling these routines from
31: *
32: * "main" (main.c)
33: * "yymain" (yymain.c)
34: * "funcend" (fend.c)
35: * "yyget" (yyget.c)
36: * "putline" (stat.c)
37: */
38:
39: #include "whoami.h"
40: #ifdef OBJ
41: /*
42: * and the rest of the file
43: */
44: #include "0.h"
45: #include "objfmt.h"
46:
47: #undef NIL
48:
49: /*
50: * pdx header files
51: */
52:
53: #include "../pdx/defs.h"
54: #include "../pdx/object.h"
55: #include "../pdx/object/objsym.rep"
56: #include "../pdx/mappings.h"
57: #include "../pdx/mappings/filetab.h"
58:
59: LOCAL char *symname = "/tmp/obj.symXXXX";
60: LOCAL char *strname = "/tmp/obj.strXXXX";
61: LOCAL char *filesname = "/tmp/obj.filesXXXX";
62: LOCAL char *linesname = "/tmp/obj.linesXXXX";
63:
64: LOCAL FILE *symfp;
65: LOCAL FILE *strfp;
66: LOCAL FILE *filesfp;
67: LOCAL FILE *linesfp;
68:
69: LOCAL long nlsize;
70:
71: extern FILE *fopen();
72:
73: /*
74: * create temporary files for the namelist info
75: */
76:
77: startnlfile()
78: {
79: nlsize = 0;
80: (void) mktemp(symname);
81: (void) mktemp(strname);
82: (void) mktemp(filesname);
83: (void) mktemp(linesname);
84: symfp = fopen(symname, "w");
85: strfp = fopen(strname, "w");
86: filesfp = fopen(filesname, "w");
87: linesfp = fopen(linesname, "w");
88: if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) {
89: fprintf(stderr, "can't create /tmp/obj");
90: pexit(NOSTART);
91: }
92: newfile(filename, 1);
93: }
94:
95: /*
96: * now copy the temp files back to obj; strings, symbols, file names, and lines
97: *
98: * There's some efficiency garbage here that uses straight system
99: * calls rather than standard I/O library calls.
100: */
101:
102: copynlfile()
103: {
104: register int n;
105: extern long lseek();
106: int symfd, strfd, filesfd, linesfd;
107: char buff[BUFSIZ];
108:
109: (void) fclose((FILE *) symfp);
110: (void) fclose((FILE *) strfp);
111: (void) fclose((FILE *) filesfp);
112: (void) fclose((FILE *) linesfp);
113: if (!opt('g')) {
114: removenlfile();
115: return;
116: }
117: symfd = open(symname, 0);
118: strfd = open(strname, 0);
119: filesfd = open(filesname, 0);
120: linesfd = open(linesname, 0);
121: if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) {
122: fprintf(stderr, "sync error on /tmp/obj");
123: pexit(ERRS);
124: }
125: (void) lseek(ofil, 0L, 2);
126: write(ofil, (char *) (&nlhdr), sizeof(nlhdr));
127: n = read(strfd, buff, BUFSIZ - sizeof(nlhdr));
128: write(ofil, buff, n);
129: cat(strfd);
130: cat(symfd);
131: cat(filesfd);
132: cat(linesfd);
133: removenlfile();
134: }
135:
136: cat(fd)
137: int fd;
138: {
139: register int n;
140: char buff[BUFSIZ];
141:
142: while ((n = read(fd, buff, BUFSIZ)) > 0) {
143: write(ofil, buff, n);
144: }
145: (void) close(fd);
146: }
147:
148: removenlfile()
149: {
150: unlink(symname);
151: unlink(strname);
152: unlink(filesname);
153: unlink(linesname);
154: }
155:
156: nlhdrsize()
157: {
158: int r;
159:
160: if (!opt('g')) {
161: r = 0;
162: } else {
163: r = nlsize + sizeof(nlhdr);
164: }
165: return r;
166: }
167:
168: #define isblock(s) (s->class == FUNC || s->class == PROC)
169: #define isbuiltin(s) ((s->nl_block&037) == 0 && isblock(s))
170: #define symno(p) (p==NULL ? 0 : nloff(p))
171:
172: struct nls {
173: struct nl *nls_low;
174: struct nl *nls_high;
175: };
176:
177: struct nl nl[], *nlp, ntab[], *nlact;
178:
179: /*VARARGS*/
180: savenl(to, rout)
181: struct nl *to;
182: {
183: register struct nl *p;
184: register OBJSYM *s;
185: OBJSYM tmpsym;
186: struct nls *nlsp;
187:
188: if (to != NIL) {
189: putblock((char *) rout);
190: } else {
191: putblock("main program");
192: }
193: nlsp = (struct nls *) nlact;
194: s = &tmpsym;
195: for (p = nlp; p != to;) {
196: if (p == nlsp->nls_low) {
197: if (nlsp == ((struct nls *) &ntab[0]))
198: break;
199: nlsp--;
200: p = nlsp->nls_high;
201: }
202: p--;
203: if (isbuiltin(p) || symno(p) == 0) {
204: continue;
205: }
206: nlhdr.nsyms++;
207: nlsize += sizeof(OBJSYM) + sizeof(int);
208: (void) putw(symno(p), symfp);
209: if (p->symbol != NULL) {
210: s->strindex = nlhdr.stringsize;
211: putstring(p->symbol);
212: } else {
213: s->strindex = 0;
214: }
215: s->oclass = p->class;
216: s->oblkno = (p->nl_block&037);
217: s->typno = symno(p->type);
218: s->chno = symno(p->chain);
219: s->osymvalue.orangev.lower = p->range[0];
220: s->osymvalue.orangev.upper = p->range[1];
221: if (isblock(p)) {
222: s->osymvalue.ofuncv.codeloc = p->value[NL_ENTLOC];
223: } else if (p->class == RECORD || p->class == VARNT) {
224: s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]);
225: s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]);
226: }
227: fwrite((char *) s, sizeof(*s), 1, symfp);
228: }
229: }
230:
231: /*
232: * Dump a line number and the current object location counter.
233: *
234: * To save space the difference from the previous line number and offset
235: * (one byte each) is dumped.
236: */
237:
238: LOCAL int oline = 0;
239: LOCAL int olc = HEADER_BYTES;
240:
241: lineno(line)
242: int line;
243: {
244: OBJLINE info;
245:
246: if (line != oline) {
247: nlhdr.nlines++;
248: nlsize += sizeof(OBJLINE);
249: info.separate.lineincr = line - oline;
250: info.separate.addrincr = ((unsigned short) (lc - olc));
251: (void) putw((int) info.together, linesfp);
252: oline = line;
253: olc = (int) lc;
254: }
255: }
256:
257: /*
258: * put out a file name entry, including:
259: *
260: * the current line number for the new file
261: * the current location counter
262: * the string table address of the file name
263: * an index into the current line number information
264: */
265:
266: newfile(s, line)
267: char *s;
268: int line;
269: {
270: FILETAB ft;
271:
272: nlhdr.nfiles++;
273: nlsize += sizeof(FILETAB);
274: ft.line = line;
275: oline = line;
276: if (lc == 0) {
277: ft.addr = 0;
278: } else {
279: ft.addr = ((LINENO) lc - HEADER_BYTES );
280: }
281: ft.filename = (char *) nlhdr.stringsize;
282: putstring(s);
283: ft.lineindex = nlhdr.nlines;
284: fwrite((char *) (&ft), sizeof(ft), 1, filesfp);
285: }
286:
287: /*
288: * put out a dummy symbol at the beginning of a block
289: */
290:
291: LOCAL putblock(s)
292: char *s;
293: {
294: static OBJSYM zerosym;
295:
296: nlhdr.nsyms++;
297: nlsize += sizeof(OBJSYM) + sizeof(int);
298: (void) putw(0, symfp);
299: zerosym.strindex = nlhdr.stringsize;
300: putstring(s);
301: fwrite((char *) (&zerosym), sizeof(zerosym), 1, symfp);
302: }
303:
304: /*
305: * put out a string to the string table file
306: */
307:
308: LOCAL putstring(s)
309: char *s;
310: {
311: register char *p;
312:
313: for (p = s; *p != '\0'; p++) {
314: putc(*p, strfp);
315: }
316: nlhdr.stringsize += (p - s + 1);
317: nlsize += (p - s + 1);
318: putc('\0', strfp);
319: }
320: #endif OBJ
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.