|
|
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.2 (Berkeley) 1/9/89";
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.symXXXXXX";
60: LOCAL char strname[] = "/tmp/obj.strXXXXXX";
61: LOCAL char filesname[] = "/tmp/obj.filesXXXXXX";
62: LOCAL char linesname[] = "/tmp/obj.linesXXXXXX";
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: LOCAL putblock();
74: LOCAL putstring();
75:
76: /*
77: * create temporary files for the namelist info
78: */
79:
80: startnlfile()
81: {
82: nlsize = 0;
83: (void) mktemp(symname);
84: (void) mktemp(strname);
85: (void) mktemp(filesname);
86: (void) mktemp(linesname);
87: symfp = fopen(symname, "w");
88: strfp = fopen(strname, "w");
89: filesfp = fopen(filesname, "w");
90: linesfp = fopen(linesname, "w");
91: if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) {
92: fprintf(stderr, "can't create /tmp/obj");
93: pexit(NOSTART);
94: }
95: newfile(filename, 1);
96: }
97:
98: /*
99: * now copy the temp files back to obj; strings, symbols, file names, and lines
100: *
101: * There's some efficiency garbage here that uses straight system
102: * calls rather than standard I/O library calls.
103: */
104:
105: copynlfile()
106: {
107: register int n;
108: extern long lseek();
109: int symfd, strfd, filesfd, linesfd;
110: char buff[BUFSIZ];
111:
112: (void) fclose((FILE *) symfp);
113: (void) fclose((FILE *) strfp);
114: (void) fclose((FILE *) filesfp);
115: (void) fclose((FILE *) linesfp);
116: if (!opt('g')) {
117: removenlfile();
118: return;
119: }
120: symfd = open(symname, 0);
121: strfd = open(strname, 0);
122: filesfd = open(filesname, 0);
123: linesfd = open(linesname, 0);
124: if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) {
125: fprintf(stderr, "sync error on /tmp/obj");
126: pexit(ERRS);
127: }
128: (void) lseek(ofil, 0L, 2);
129: write(ofil, (char *) (&nlhdr), sizeof(nlhdr));
130: n = read(strfd, buff, BUFSIZ - sizeof(nlhdr));
131: write(ofil, buff, n);
132: cat(strfd);
133: cat(symfd);
134: cat(filesfd);
135: cat(linesfd);
136: removenlfile();
137: }
138:
139: cat(fd)
140: int fd;
141: {
142: register int n;
143: char buff[BUFSIZ];
144:
145: while ((n = read(fd, buff, BUFSIZ)) > 0) {
146: write(ofil, buff, n);
147: }
148: (void) close(fd);
149: }
150:
151: removenlfile()
152: {
153: unlink(symname);
154: unlink(strname);
155: unlink(filesname);
156: unlink(linesname);
157: }
158:
159: nlhdrsize()
160: {
161: int r;
162:
163: if (!opt('g')) {
164: r = 0;
165: } else {
166: r = nlsize + sizeof(nlhdr);
167: }
168: return r;
169: }
170:
171: #define isblock(s) (s->class == FUNC || s->class == PROC)
172: #define isbuiltin(s) ((s->nl_block&037) == 0 && isblock(s))
173: #define symno(p) (p==NULL ? 0 : nloff(p))
174:
175: struct nls {
176: struct nl *nls_low;
177: struct nl *nls_high;
178: };
179:
180: struct nl nl[], *nlp, ntab[], *nlact;
181:
182: /*VARARGS*/
183: savenl(to, rout)
184: struct nl *to;
185: {
186: register struct nl *p;
187: register OBJSYM *s;
188: OBJSYM tmpsym;
189: struct nls *nlsp;
190:
191: if (to != NIL) {
192: putblock((char *) rout);
193: } else {
194: putblock("main program");
195: }
196: nlsp = (struct nls *) nlact;
197: s = &tmpsym;
198: for (p = nlp; p != to;) {
199: if (p == nlsp->nls_low) {
200: if (nlsp == ((struct nls *) &ntab[0]))
201: break;
202: nlsp--;
203: p = nlsp->nls_high;
204: }
205: p--;
206: if (isbuiltin(p) || symno(p) == 0) {
207: continue;
208: }
209: nlhdr.nsyms++;
210: nlsize += sizeof(OBJSYM) + sizeof(int);
211: (void) putw(symno(p), symfp);
212: if (p->symbol != NULL) {
213: s->strindex = nlhdr.stringsize;
214: putstring(p->symbol);
215: } else {
216: s->strindex = 0;
217: }
218: s->oclass = p->class;
219: s->oblkno = (p->nl_block&037);
220: s->typno = symno(p->type);
221: s->chno = symno(p->chain);
222: s->osymvalue.orangev.lower = p->range[0];
223: s->osymvalue.orangev.upper = p->range[1];
224: if (isblock(p)) {
225: s->osymvalue.ofuncv.codeloc = p->value[NL_ENTLOC];
226: } else if (p->class == RECORD || p->class == VARNT) {
227: s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]);
228: s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]);
229: }
230: fwrite((char *) s, sizeof(*s), 1, symfp);
231: }
232: }
233:
234: /*
235: * Dump a line number and the current object location counter.
236: *
237: * To save space the difference from the previous line number and offset
238: * (one byte each) is dumped.
239: */
240:
241: LOCAL int oline = 0;
242: LOCAL int olc = HEADER_BYTES;
243:
244: lineno(line)
245: int line;
246: {
247: OBJLINE info;
248:
249: if (line != oline) {
250: nlhdr.nlines++;
251: nlsize += sizeof(OBJLINE);
252: info.separate.lineincr = line - oline;
253: info.separate.addrincr = ((unsigned short) (lc - olc));
254: (void) putw((int) info.together, linesfp);
255: oline = line;
256: olc = (int) lc;
257: }
258: }
259:
260: /*
261: * put out a file name entry, including:
262: *
263: * the current line number for the new file
264: * the current location counter
265: * the string table address of the file name
266: * an index into the current line number information
267: */
268:
269: newfile(s, line)
270: char *s;
271: int line;
272: {
273: FILETAB ft;
274:
275: nlhdr.nfiles++;
276: nlsize += sizeof(FILETAB);
277: ft.line = line;
278: oline = line;
279: if (lc == 0) {
280: ft.addr = 0;
281: } else {
282: ft.addr = ((LINENO) lc - HEADER_BYTES );
283: }
284: ft.filename = (char *) nlhdr.stringsize;
285: putstring(s);
286: ft.lineindex = nlhdr.nlines;
287: fwrite((char *) (&ft), sizeof(ft), 1, filesfp);
288: }
289:
290: /*
291: * put out a dummy symbol at the beginning of a block
292: */
293:
294: LOCAL putblock(s)
295: char *s;
296: {
297: static OBJSYM zerosym;
298:
299: nlhdr.nsyms++;
300: nlsize += sizeof(OBJSYM) + sizeof(int);
301: (void) putw(0, symfp);
302: zerosym.strindex = nlhdr.stringsize;
303: putstring(s);
304: fwrite((char *) (&zerosym), sizeof(zerosym), 1, symfp);
305: }
306:
307: /*
308: * put out a string to the string table file
309: */
310:
311: LOCAL putstring(s)
312: char *s;
313: {
314: register char *p;
315:
316: for (p = s; *p != '\0'; p++) {
317: putc(*p, strfp);
318: }
319: nlhdr.stringsize += (p - s + 1);
320: nlsize += (p - s + 1);
321: putc('\0', strfp);
322: }
323: #endif OBJ
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.