148116Sbostic /*-
262215Sbostic * Copyright (c) 1980, 1993
362215Sbostic * The Regents of the University of California. All rights reserved.
448116Sbostic *
548116Sbostic * %sccs.include.redist.c%
622189Sdist */
75446Slinton
814742Sthien #ifndef lint
9*67239Smckusick static char sccsid[] = "@(#)savenl.c 8.2 (Berkeley) 05/24/94";
1048116Sbostic #endif /* not lint */
115446Slinton
125446Slinton /*
135446Slinton * savenl - routines for saving namelist and line number information
145446Slinton *
155446Slinton * This module contains the routines that make pi dump a namelist
165446Slinton * at the end of the object file. We do this by first creating
175446Slinton * four temporary files in "startnlfile". One temp file contains
185446Slinton * the string table, one the symbol table, one the file name
195446Slinton * information and one the line number information.
205446Slinton *
215446Slinton * Prior to generation of the code for a statement the "lineno"
225446Slinton * routine is called to dump the line number and current object
235446Slinton * address. At the end of each block "savenl" is called to dump
245446Slinton * the strings and symbol structures.
255446Slinton *
265446Slinton * At the end of execution "copynlfile" is called and it copies
275446Slinton * the temp files onto the end of the obj file.
285446Slinton *
295446Slinton * In case of error, "removenlfile" is called to destroy the temp files.
305446Slinton *
315446Slinton * The only other changes to pi are in calling these routines from
325446Slinton *
335446Slinton * "main" (main.c)
345446Slinton * "yymain" (yymain.c)
355446Slinton * "funcend" (fend.c)
365446Slinton * "yyget" (yyget.c)
375446Slinton * "putline" (stat.c)
385446Slinton */
395446Slinton
405446Slinton #include "whoami.h"
416427Speter #ifdef OBJ
426427Speter /*
436427Speter * and the rest of the file
446427Speter */
455446Slinton #include "0.h"
465655Slinton #include "objfmt.h"
475446Slinton
485446Slinton #undef NIL
495446Slinton
505446Slinton /*
515446Slinton * pdx header files
525446Slinton */
535446Slinton
546427Speter #include "../pdx/defs.h"
556427Speter #include "../pdx/object.h"
566427Speter #include "../pdx/object/objsym.rep"
576427Speter #include "../pdx/mappings.h"
586427Speter #include "../pdx/mappings/filetab.h"
595446Slinton
6036536Smckusick LOCAL char symname[] = "/tmp/obj.symXXXXXX";
6136536Smckusick LOCAL char strname[] = "/tmp/obj.strXXXXXX";
6236536Smckusick LOCAL char filesname[] = "/tmp/obj.filesXXXXXX";
6336536Smckusick LOCAL char linesname[] = "/tmp/obj.linesXXXXXX";
645446Slinton
655446Slinton LOCAL FILE *symfp;
665446Slinton LOCAL FILE *strfp;
675446Slinton LOCAL FILE *filesfp;
685446Slinton LOCAL FILE *linesfp;
695446Slinton
705655Slinton LOCAL long nlsize;
715655Slinton
7214742Sthien extern FILE *fopen();
7314742Sthien
7436536Smckusick LOCAL putblock();
7536536Smckusick LOCAL putstring();
7636536Smckusick
775446Slinton /*
785446Slinton * create temporary files for the namelist info
795446Slinton */
805446Slinton
startnlfile()815446Slinton startnlfile()
825446Slinton {
835655Slinton nlsize = 0;
8414742Sthien (void) mktemp(symname);
8514742Sthien (void) mktemp(strname);
8614742Sthien (void) mktemp(filesname);
8714742Sthien (void) mktemp(linesname);
885446Slinton symfp = fopen(symname, "w");
895446Slinton strfp = fopen(strname, "w");
905446Slinton filesfp = fopen(filesname, "w");
915446Slinton linesfp = fopen(linesname, "w");
925446Slinton if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) {
935446Slinton fprintf(stderr, "can't create /tmp/obj");
945446Slinton pexit(NOSTART);
955446Slinton }
965446Slinton newfile(filename, 1);
975446Slinton }
985446Slinton
995446Slinton /*
1005446Slinton * now copy the temp files back to obj; strings, symbols, file names, and lines
1015446Slinton *
1025446Slinton * There's some efficiency garbage here that uses straight system
1035446Slinton * calls rather than standard I/O library calls.
1045446Slinton */
1055446Slinton
copynlfile()1065446Slinton copynlfile()
1075446Slinton {
1085446Slinton register int n;
1095446Slinton int symfd, strfd, filesfd, linesfd;
1105446Slinton char buff[BUFSIZ];
1115446Slinton
11214742Sthien (void) fclose((FILE *) symfp);
11314742Sthien (void) fclose((FILE *) strfp);
11414742Sthien (void) fclose((FILE *) filesfp);
11514742Sthien (void) fclose((FILE *) linesfp);
1165655Slinton if (!opt('g')) {
1175655Slinton removenlfile();
1185655Slinton return;
1195655Slinton }
1205446Slinton symfd = open(symname, 0);
1215446Slinton strfd = open(strname, 0);
1225446Slinton filesfd = open(filesname, 0);
1235446Slinton linesfd = open(linesname, 0);
1245446Slinton if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) {
1255446Slinton fprintf(stderr, "sync error on /tmp/obj");
1265446Slinton pexit(ERRS);
1275446Slinton }
128*67239Smckusick if (lseek(ofil, (off_t)0, 2) == -1)
129*67239Smckusick perror("copynlfile: lseek"), panic("copynlfile");
13014742Sthien write(ofil, (char *) (&nlhdr), sizeof(nlhdr));
1315446Slinton n = read(strfd, buff, BUFSIZ - sizeof(nlhdr));
1325446Slinton write(ofil, buff, n);
1335446Slinton cat(strfd);
1345446Slinton cat(symfd);
1355446Slinton cat(filesfd);
1365446Slinton cat(linesfd);
1375446Slinton removenlfile();
1385446Slinton }
1395446Slinton
cat(fd)1405446Slinton cat(fd)
1415446Slinton int fd;
1425446Slinton {
1435446Slinton register int n;
1445446Slinton char buff[BUFSIZ];
1455446Slinton
1465446Slinton while ((n = read(fd, buff, BUFSIZ)) > 0) {
1475446Slinton write(ofil, buff, n);
1485446Slinton }
14914742Sthien (void) close(fd);
1505446Slinton }
1515446Slinton
removenlfile()1525446Slinton removenlfile()
1535446Slinton {
1545446Slinton unlink(symname);
1555446Slinton unlink(strname);
1565446Slinton unlink(filesname);
1575446Slinton unlink(linesname);
1585446Slinton }
1595446Slinton
nlhdrsize()1605655Slinton nlhdrsize()
1615655Slinton {
1625655Slinton int r;
1635655Slinton
1645655Slinton if (!opt('g')) {
1655655Slinton r = 0;
1665655Slinton } else {
1675655Slinton r = nlsize + sizeof(nlhdr);
1685655Slinton }
1695655Slinton return r;
1705655Slinton }
1715655Slinton
1725446Slinton #define isblock(s) (s->class == FUNC || s->class == PROC)
1735446Slinton #define isbuiltin(s) ((s->nl_block&037) == 0 && isblock(s))
1745446Slinton #define symno(p) (p==NULL ? 0 : nloff(p))
1755446Slinton
1765446Slinton struct nls {
1775446Slinton struct nl *nls_low;
1785446Slinton struct nl *nls_high;
1795446Slinton };
1805446Slinton
1815446Slinton struct nl nl[], *nlp, ntab[], *nlact;
1825446Slinton
18314742Sthien /*VARARGS*/
1845446Slinton savenl(to, rout)
1855446Slinton struct nl *to;
1865446Slinton {
1875446Slinton register struct nl *p;
1885446Slinton register OBJSYM *s;
1895446Slinton OBJSYM tmpsym;
1905446Slinton struct nls *nlsp;
1915446Slinton
1925446Slinton if (to != NIL) {
19314742Sthien putblock((char *) rout);
1945446Slinton } else {
1955446Slinton putblock("main program");
1965446Slinton }
19714742Sthien nlsp = (struct nls *) nlact;
1985446Slinton s = &tmpsym;
1995446Slinton for (p = nlp; p != to;) {
2005446Slinton if (p == nlsp->nls_low) {
20114742Sthien if (nlsp == ((struct nls *) &ntab[0]))
2025446Slinton break;
2035446Slinton nlsp--;
2045446Slinton p = nlsp->nls_high;
2055446Slinton }
2065446Slinton p--;
2075446Slinton if (isbuiltin(p) || symno(p) == 0) {
2085446Slinton continue;
2095446Slinton }
2105446Slinton nlhdr.nsyms++;
2115655Slinton nlsize += sizeof(OBJSYM) + sizeof(int);
21214742Sthien (void) putw(symno(p), symfp);
2135446Slinton if (p->symbol != NULL) {
2145446Slinton s->strindex = nlhdr.stringsize;
2155446Slinton putstring(p->symbol);
2165446Slinton } else {
2175446Slinton s->strindex = 0;
2185446Slinton }
2195446Slinton s->oclass = p->class;
2205446Slinton s->oblkno = (p->nl_block&037);
2215446Slinton s->typno = symno(p->type);
2225446Slinton s->chno = symno(p->chain);
2235446Slinton s->osymvalue.orangev.lower = p->range[0];
2245446Slinton s->osymvalue.orangev.upper = p->range[1];
2255446Slinton if (isblock(p)) {
2267919Smckusick s->osymvalue.ofuncv.codeloc = p->value[NL_ENTLOC];
2275446Slinton } else if (p->class == RECORD || p->class == VARNT) {
2285446Slinton s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]);
2295446Slinton s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]);
2305446Slinton }
23114742Sthien fwrite((char *) s, sizeof(*s), 1, symfp);
2325446Slinton }
2335446Slinton }
2345446Slinton
2355446Slinton /*
2365446Slinton * Dump a line number and the current object location counter.
2375446Slinton *
2385446Slinton * To save space the difference from the previous line number and offset
2395446Slinton * (one byte each) is dumped.
2405446Slinton */
2415446Slinton
2425446Slinton LOCAL int oline = 0;
2435655Slinton LOCAL int olc = HEADER_BYTES;
2445446Slinton
lineno(line)2455446Slinton lineno(line)
2465446Slinton int line;
2475446Slinton {
2485755Slinton OBJLINE info;
2495755Slinton
2505446Slinton if (line != oline) {
2515446Slinton nlhdr.nlines++;
2525755Slinton nlsize += sizeof(OBJLINE);
2535755Slinton info.separate.lineincr = line - oline;
25414742Sthien info.separate.addrincr = ((unsigned short) (lc - olc));
25514742Sthien (void) putw((int) info.together, linesfp);
2565446Slinton oline = line;
25714742Sthien olc = (int) lc;
2585446Slinton }
2595446Slinton }
2605446Slinton
2615446Slinton /*
2625446Slinton * put out a file name entry, including:
2635446Slinton *
2645446Slinton * the current line number for the new file
2655446Slinton * the current location counter
2665446Slinton * the string table address of the file name
2675446Slinton * an index into the current line number information
2685446Slinton */
2695446Slinton
newfile(s,line)2705446Slinton newfile(s, line)
2715446Slinton char *s;
2725446Slinton int line;
2735446Slinton {
2745446Slinton FILETAB ft;
2755446Slinton
2765446Slinton nlhdr.nfiles++;
2775655Slinton nlsize += sizeof(FILETAB);
2785446Slinton ft.line = line;
2795446Slinton oline = line;
2805446Slinton if (lc == 0) {
2815446Slinton ft.addr = 0;
2825446Slinton } else {
28314742Sthien ft.addr = ((LINENO) lc - HEADER_BYTES );
2845446Slinton }
2855446Slinton ft.filename = (char *) nlhdr.stringsize;
2865446Slinton putstring(s);
2875446Slinton ft.lineindex = nlhdr.nlines;
28814742Sthien fwrite((char *) (&ft), sizeof(ft), 1, filesfp);
2895446Slinton }
2905446Slinton
2915446Slinton /*
2925446Slinton * put out a dummy symbol at the beginning of a block
2935446Slinton */
2945446Slinton
putblock(s)2955446Slinton LOCAL putblock(s)
2965446Slinton char *s;
2975446Slinton {
2985446Slinton static OBJSYM zerosym;
2995446Slinton
3005446Slinton nlhdr.nsyms++;
3015655Slinton nlsize += sizeof(OBJSYM) + sizeof(int);
30214742Sthien (void) putw(0, symfp);
3035446Slinton zerosym.strindex = nlhdr.stringsize;
3045446Slinton putstring(s);
30514742Sthien fwrite((char *) (&zerosym), sizeof(zerosym), 1, symfp);
3065446Slinton }
3075446Slinton
3085446Slinton /*
3095446Slinton * put out a string to the string table file
3105446Slinton */
3115446Slinton
putstring(s)3125446Slinton LOCAL putstring(s)
3135446Slinton char *s;
3145446Slinton {
3155446Slinton register char *p;
3165446Slinton
3175655Slinton for (p = s; *p != '\0'; p++) {
3185446Slinton putc(*p, strfp);
3195655Slinton }
3205446Slinton nlhdr.stringsize += (p - s + 1);
3215655Slinton nlsize += (p - s + 1);
3225446Slinton putc('\0', strfp);
3235446Slinton }
3246427Speter #endif OBJ
325