148116Sbostic /*- 2*62215Sbostic * Copyright (c) 1980, 1993 3*62215Sbostic * The Regents of the University of California. All rights reserved. 448116Sbostic * 548116Sbostic * %sccs.include.redist.c% 622189Sdist */ 75446Slinton 814742Sthien #ifndef lint 9*62215Sbostic static char sccsid[] = "@(#)savenl.c 8.1 (Berkeley) 06/06/93"; 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 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 1065446Slinton copynlfile() 1075446Slinton { 1085446Slinton register int n; 10914742Sthien extern long lseek(); 1105446Slinton int symfd, strfd, filesfd, linesfd; 1115446Slinton char buff[BUFSIZ]; 1125446Slinton 11314742Sthien (void) fclose((FILE *) symfp); 11414742Sthien (void) fclose((FILE *) strfp); 11514742Sthien (void) fclose((FILE *) filesfp); 11614742Sthien (void) fclose((FILE *) linesfp); 1175655Slinton if (!opt('g')) { 1185655Slinton removenlfile(); 1195655Slinton return; 1205655Slinton } 1215446Slinton symfd = open(symname, 0); 1225446Slinton strfd = open(strname, 0); 1235446Slinton filesfd = open(filesname, 0); 1245446Slinton linesfd = open(linesname, 0); 1255446Slinton if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) { 1265446Slinton fprintf(stderr, "sync error on /tmp/obj"); 1275446Slinton pexit(ERRS); 1285446Slinton } 12914742Sthien (void) lseek(ofil, 0L, 2); 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 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 1525446Slinton removenlfile() 1535446Slinton { 1545446Slinton unlink(symname); 1555446Slinton unlink(strname); 1565446Slinton unlink(filesname); 1575446Slinton unlink(linesname); 1585446Slinton } 1595446Slinton 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 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 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 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 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