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