122189Sdist /* 222189Sdist * Copyright (c) 1980 Regents of the University of California. 322189Sdist * All rights reserved. The Berkeley software License Agreement 422189Sdist * specifies the terms and conditions for redistribution. 522189Sdist */ 65446Slinton 714742Sthien #ifndef lint 8*36536Smckusick static char sccsid[] = "@(#)savenl.c 5.2 (Berkeley) 01/09/89"; 922189Sdist #endif not lint 105446Slinton 115446Slinton /* 125446Slinton * savenl - routines for saving namelist and line number information 135446Slinton * 145446Slinton * This module contains the routines that make pi dump a namelist 155446Slinton * at the end of the object file. We do this by first creating 165446Slinton * four temporary files in "startnlfile". One temp file contains 175446Slinton * the string table, one the symbol table, one the file name 185446Slinton * information and one the line number information. 195446Slinton * 205446Slinton * Prior to generation of the code for a statement the "lineno" 215446Slinton * routine is called to dump the line number and current object 225446Slinton * address. At the end of each block "savenl" is called to dump 235446Slinton * the strings and symbol structures. 245446Slinton * 255446Slinton * At the end of execution "copynlfile" is called and it copies 265446Slinton * the temp files onto the end of the obj file. 275446Slinton * 285446Slinton * In case of error, "removenlfile" is called to destroy the temp files. 295446Slinton * 305446Slinton * The only other changes to pi are in calling these routines from 315446Slinton * 325446Slinton * "main" (main.c) 335446Slinton * "yymain" (yymain.c) 345446Slinton * "funcend" (fend.c) 355446Slinton * "yyget" (yyget.c) 365446Slinton * "putline" (stat.c) 375446Slinton */ 385446Slinton 395446Slinton #include "whoami.h" 406427Speter #ifdef OBJ 416427Speter /* 426427Speter * and the rest of the file 436427Speter */ 445446Slinton #include "0.h" 455655Slinton #include "objfmt.h" 465446Slinton 475446Slinton #undef NIL 485446Slinton 495446Slinton /* 505446Slinton * pdx header files 515446Slinton */ 525446Slinton 536427Speter #include "../pdx/defs.h" 546427Speter #include "../pdx/object.h" 556427Speter #include "../pdx/object/objsym.rep" 566427Speter #include "../pdx/mappings.h" 576427Speter #include "../pdx/mappings/filetab.h" 585446Slinton 59*36536Smckusick LOCAL char symname[] = "/tmp/obj.symXXXXXX"; 60*36536Smckusick LOCAL char strname[] = "/tmp/obj.strXXXXXX"; 61*36536Smckusick LOCAL char filesname[] = "/tmp/obj.filesXXXXXX"; 62*36536Smckusick LOCAL char linesname[] = "/tmp/obj.linesXXXXXX"; 635446Slinton 645446Slinton LOCAL FILE *symfp; 655446Slinton LOCAL FILE *strfp; 665446Slinton LOCAL FILE *filesfp; 675446Slinton LOCAL FILE *linesfp; 685446Slinton 695655Slinton LOCAL long nlsize; 705655Slinton 7114742Sthien extern FILE *fopen(); 7214742Sthien 73*36536Smckusick LOCAL putblock(); 74*36536Smckusick LOCAL putstring(); 75*36536Smckusick 765446Slinton /* 775446Slinton * create temporary files for the namelist info 785446Slinton */ 795446Slinton 805446Slinton startnlfile() 815446Slinton { 825655Slinton nlsize = 0; 8314742Sthien (void) mktemp(symname); 8414742Sthien (void) mktemp(strname); 8514742Sthien (void) mktemp(filesname); 8614742Sthien (void) mktemp(linesname); 875446Slinton symfp = fopen(symname, "w"); 885446Slinton strfp = fopen(strname, "w"); 895446Slinton filesfp = fopen(filesname, "w"); 905446Slinton linesfp = fopen(linesname, "w"); 915446Slinton if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) { 925446Slinton fprintf(stderr, "can't create /tmp/obj"); 935446Slinton pexit(NOSTART); 945446Slinton } 955446Slinton newfile(filename, 1); 965446Slinton } 975446Slinton 985446Slinton /* 995446Slinton * now copy the temp files back to obj; strings, symbols, file names, and lines 1005446Slinton * 1015446Slinton * There's some efficiency garbage here that uses straight system 1025446Slinton * calls rather than standard I/O library calls. 1035446Slinton */ 1045446Slinton 1055446Slinton copynlfile() 1065446Slinton { 1075446Slinton register int n; 10814742Sthien extern long lseek(); 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 } 12814742Sthien (void) lseek(ofil, 0L, 2); 12914742Sthien write(ofil, (char *) (&nlhdr), sizeof(nlhdr)); 1305446Slinton n = read(strfd, buff, BUFSIZ - sizeof(nlhdr)); 1315446Slinton write(ofil, buff, n); 1325446Slinton cat(strfd); 1335446Slinton cat(symfd); 1345446Slinton cat(filesfd); 1355446Slinton cat(linesfd); 1365446Slinton removenlfile(); 1375446Slinton } 1385446Slinton 1395446Slinton cat(fd) 1405446Slinton int fd; 1415446Slinton { 1425446Slinton register int n; 1435446Slinton char buff[BUFSIZ]; 1445446Slinton 1455446Slinton while ((n = read(fd, buff, BUFSIZ)) > 0) { 1465446Slinton write(ofil, buff, n); 1475446Slinton } 14814742Sthien (void) close(fd); 1495446Slinton } 1505446Slinton 1515446Slinton removenlfile() 1525446Slinton { 1535446Slinton unlink(symname); 1545446Slinton unlink(strname); 1555446Slinton unlink(filesname); 1565446Slinton unlink(linesname); 1575446Slinton } 1585446Slinton 1595655Slinton nlhdrsize() 1605655Slinton { 1615655Slinton int r; 1625655Slinton 1635655Slinton if (!opt('g')) { 1645655Slinton r = 0; 1655655Slinton } else { 1665655Slinton r = nlsize + sizeof(nlhdr); 1675655Slinton } 1685655Slinton return r; 1695655Slinton } 1705655Slinton 1715446Slinton #define isblock(s) (s->class == FUNC || s->class == PROC) 1725446Slinton #define isbuiltin(s) ((s->nl_block&037) == 0 && isblock(s)) 1735446Slinton #define symno(p) (p==NULL ? 0 : nloff(p)) 1745446Slinton 1755446Slinton struct nls { 1765446Slinton struct nl *nls_low; 1775446Slinton struct nl *nls_high; 1785446Slinton }; 1795446Slinton 1805446Slinton struct nl nl[], *nlp, ntab[], *nlact; 1815446Slinton 18214742Sthien /*VARARGS*/ 1835446Slinton savenl(to, rout) 1845446Slinton struct nl *to; 1855446Slinton { 1865446Slinton register struct nl *p; 1875446Slinton register OBJSYM *s; 1885446Slinton OBJSYM tmpsym; 1895446Slinton struct nls *nlsp; 1905446Slinton 1915446Slinton if (to != NIL) { 19214742Sthien putblock((char *) rout); 1935446Slinton } else { 1945446Slinton putblock("main program"); 1955446Slinton } 19614742Sthien nlsp = (struct nls *) nlact; 1975446Slinton s = &tmpsym; 1985446Slinton for (p = nlp; p != to;) { 1995446Slinton if (p == nlsp->nls_low) { 20014742Sthien if (nlsp == ((struct nls *) &ntab[0])) 2015446Slinton break; 2025446Slinton nlsp--; 2035446Slinton p = nlsp->nls_high; 2045446Slinton } 2055446Slinton p--; 2065446Slinton if (isbuiltin(p) || symno(p) == 0) { 2075446Slinton continue; 2085446Slinton } 2095446Slinton nlhdr.nsyms++; 2105655Slinton nlsize += sizeof(OBJSYM) + sizeof(int); 21114742Sthien (void) putw(symno(p), symfp); 2125446Slinton if (p->symbol != NULL) { 2135446Slinton s->strindex = nlhdr.stringsize; 2145446Slinton putstring(p->symbol); 2155446Slinton } else { 2165446Slinton s->strindex = 0; 2175446Slinton } 2185446Slinton s->oclass = p->class; 2195446Slinton s->oblkno = (p->nl_block&037); 2205446Slinton s->typno = symno(p->type); 2215446Slinton s->chno = symno(p->chain); 2225446Slinton s->osymvalue.orangev.lower = p->range[0]; 2235446Slinton s->osymvalue.orangev.upper = p->range[1]; 2245446Slinton if (isblock(p)) { 2257919Smckusick s->osymvalue.ofuncv.codeloc = p->value[NL_ENTLOC]; 2265446Slinton } else if (p->class == RECORD || p->class == VARNT) { 2275446Slinton s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]); 2285446Slinton s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]); 2295446Slinton } 23014742Sthien fwrite((char *) s, sizeof(*s), 1, symfp); 2315446Slinton } 2325446Slinton } 2335446Slinton 2345446Slinton /* 2355446Slinton * Dump a line number and the current object location counter. 2365446Slinton * 2375446Slinton * To save space the difference from the previous line number and offset 2385446Slinton * (one byte each) is dumped. 2395446Slinton */ 2405446Slinton 2415446Slinton LOCAL int oline = 0; 2425655Slinton LOCAL int olc = HEADER_BYTES; 2435446Slinton 2445446Slinton lineno(line) 2455446Slinton int line; 2465446Slinton { 2475755Slinton OBJLINE info; 2485755Slinton 2495446Slinton if (line != oline) { 2505446Slinton nlhdr.nlines++; 2515755Slinton nlsize += sizeof(OBJLINE); 2525755Slinton info.separate.lineincr = line - oline; 25314742Sthien info.separate.addrincr = ((unsigned short) (lc - olc)); 25414742Sthien (void) putw((int) info.together, linesfp); 2555446Slinton oline = line; 25614742Sthien olc = (int) lc; 2575446Slinton } 2585446Slinton } 2595446Slinton 2605446Slinton /* 2615446Slinton * put out a file name entry, including: 2625446Slinton * 2635446Slinton * the current line number for the new file 2645446Slinton * the current location counter 2655446Slinton * the string table address of the file name 2665446Slinton * an index into the current line number information 2675446Slinton */ 2685446Slinton 2695446Slinton newfile(s, line) 2705446Slinton char *s; 2715446Slinton int line; 2725446Slinton { 2735446Slinton FILETAB ft; 2745446Slinton 2755446Slinton nlhdr.nfiles++; 2765655Slinton nlsize += sizeof(FILETAB); 2775446Slinton ft.line = line; 2785446Slinton oline = line; 2795446Slinton if (lc == 0) { 2805446Slinton ft.addr = 0; 2815446Slinton } else { 28214742Sthien ft.addr = ((LINENO) lc - HEADER_BYTES ); 2835446Slinton } 2845446Slinton ft.filename = (char *) nlhdr.stringsize; 2855446Slinton putstring(s); 2865446Slinton ft.lineindex = nlhdr.nlines; 28714742Sthien fwrite((char *) (&ft), sizeof(ft), 1, filesfp); 2885446Slinton } 2895446Slinton 2905446Slinton /* 2915446Slinton * put out a dummy symbol at the beginning of a block 2925446Slinton */ 2935446Slinton 2945446Slinton LOCAL putblock(s) 2955446Slinton char *s; 2965446Slinton { 2975446Slinton static OBJSYM zerosym; 2985446Slinton 2995446Slinton nlhdr.nsyms++; 3005655Slinton nlsize += sizeof(OBJSYM) + sizeof(int); 30114742Sthien (void) putw(0, symfp); 3025446Slinton zerosym.strindex = nlhdr.stringsize; 3035446Slinton putstring(s); 30414742Sthien fwrite((char *) (&zerosym), sizeof(zerosym), 1, symfp); 3055446Slinton } 3065446Slinton 3075446Slinton /* 3085446Slinton * put out a string to the string table file 3095446Slinton */ 3105446Slinton 3115446Slinton LOCAL putstring(s) 3125446Slinton char *s; 3135446Slinton { 3145446Slinton register char *p; 3155446Slinton 3165655Slinton for (p = s; *p != '\0'; p++) { 3175446Slinton putc(*p, strfp); 3185655Slinton } 3195446Slinton nlhdr.stringsize += (p - s + 1); 3205655Slinton nlsize += (p - s + 1); 3215446Slinton putc('\0', strfp); 3225446Slinton } 3236427Speter #endif OBJ 324