15446Slinton /* Copyright (c) 1982 Regents of the University of California */ 25446Slinton 3*14742Sthien #ifndef lint 4*14742Sthien static char sccsid[] = "@(#)savenl.c 1.6 08/19/83"; 5*14742Sthien #endif 65446Slinton 75446Slinton /* 85446Slinton * savenl - routines for saving namelist and line number information 95446Slinton * 105446Slinton * This module contains the routines that make pi dump a namelist 115446Slinton * at the end of the object file. We do this by first creating 125446Slinton * four temporary files in "startnlfile". One temp file contains 135446Slinton * the string table, one the symbol table, one the file name 145446Slinton * information and one the line number information. 155446Slinton * 165446Slinton * Prior to generation of the code for a statement the "lineno" 175446Slinton * routine is called to dump the line number and current object 185446Slinton * address. At the end of each block "savenl" is called to dump 195446Slinton * the strings and symbol structures. 205446Slinton * 215446Slinton * At the end of execution "copynlfile" is called and it copies 225446Slinton * the temp files onto the end of the obj file. 235446Slinton * 245446Slinton * In case of error, "removenlfile" is called to destroy the temp files. 255446Slinton * 265446Slinton * The only other changes to pi are in calling these routines from 275446Slinton * 285446Slinton * "main" (main.c) 295446Slinton * "yymain" (yymain.c) 305446Slinton * "funcend" (fend.c) 315446Slinton * "yyget" (yyget.c) 325446Slinton * "putline" (stat.c) 335446Slinton */ 345446Slinton 355446Slinton #include "whoami.h" 366427Speter #ifdef OBJ 376427Speter /* 386427Speter * and the rest of the file 396427Speter */ 405446Slinton #include "0.h" 415655Slinton #include "objfmt.h" 425446Slinton 435446Slinton #undef NIL 445446Slinton 455446Slinton /* 465446Slinton * pdx header files 475446Slinton */ 485446Slinton 496427Speter #include "../pdx/defs.h" 506427Speter #include "../pdx/object.h" 516427Speter #include "../pdx/object/objsym.rep" 526427Speter #include "../pdx/mappings.h" 536427Speter #include "../pdx/mappings/filetab.h" 545446Slinton 555446Slinton LOCAL char *symname = "/tmp/obj.symXXXX"; 565446Slinton LOCAL char *strname = "/tmp/obj.strXXXX"; 575446Slinton LOCAL char *filesname = "/tmp/obj.filesXXXX"; 585446Slinton LOCAL char *linesname = "/tmp/obj.linesXXXX"; 595446Slinton 605446Slinton LOCAL FILE *symfp; 615446Slinton LOCAL FILE *strfp; 625446Slinton LOCAL FILE *filesfp; 635446Slinton LOCAL FILE *linesfp; 645446Slinton 655655Slinton LOCAL long nlsize; 665655Slinton 67*14742Sthien extern FILE *fopen(); 68*14742Sthien 695446Slinton /* 705446Slinton * create temporary files for the namelist info 715446Slinton */ 725446Slinton 735446Slinton startnlfile() 745446Slinton { 755655Slinton nlsize = 0; 76*14742Sthien (void) mktemp(symname); 77*14742Sthien (void) mktemp(strname); 78*14742Sthien (void) mktemp(filesname); 79*14742Sthien (void) mktemp(linesname); 805446Slinton symfp = fopen(symname, "w"); 815446Slinton strfp = fopen(strname, "w"); 825446Slinton filesfp = fopen(filesname, "w"); 835446Slinton linesfp = fopen(linesname, "w"); 845446Slinton if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) { 855446Slinton fprintf(stderr, "can't create /tmp/obj"); 865446Slinton pexit(NOSTART); 875446Slinton } 885446Slinton newfile(filename, 1); 895446Slinton } 905446Slinton 915446Slinton /* 925446Slinton * now copy the temp files back to obj; strings, symbols, file names, and lines 935446Slinton * 945446Slinton * There's some efficiency garbage here that uses straight system 955446Slinton * calls rather than standard I/O library calls. 965446Slinton */ 975446Slinton 985446Slinton copynlfile() 995446Slinton { 1005446Slinton register int n; 101*14742Sthien extern long lseek(); 1025446Slinton int symfd, strfd, filesfd, linesfd; 1035446Slinton char buff[BUFSIZ]; 1045446Slinton 105*14742Sthien (void) fclose((FILE *) symfp); 106*14742Sthien (void) fclose((FILE *) strfp); 107*14742Sthien (void) fclose((FILE *) filesfp); 108*14742Sthien (void) fclose((FILE *) linesfp); 1095655Slinton if (!opt('g')) { 1105655Slinton removenlfile(); 1115655Slinton return; 1125655Slinton } 1135446Slinton symfd = open(symname, 0); 1145446Slinton strfd = open(strname, 0); 1155446Slinton filesfd = open(filesname, 0); 1165446Slinton linesfd = open(linesname, 0); 1175446Slinton if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) { 1185446Slinton fprintf(stderr, "sync error on /tmp/obj"); 1195446Slinton pexit(ERRS); 1205446Slinton } 121*14742Sthien (void) lseek(ofil, 0L, 2); 122*14742Sthien write(ofil, (char *) (&nlhdr), sizeof(nlhdr)); 1235446Slinton n = read(strfd, buff, BUFSIZ - sizeof(nlhdr)); 1245446Slinton write(ofil, buff, n); 1255446Slinton cat(strfd); 1265446Slinton cat(symfd); 1275446Slinton cat(filesfd); 1285446Slinton cat(linesfd); 1295446Slinton removenlfile(); 1305446Slinton } 1315446Slinton 1325446Slinton cat(fd) 1335446Slinton int fd; 1345446Slinton { 1355446Slinton register int n; 1365446Slinton char buff[BUFSIZ]; 1375446Slinton 1385446Slinton while ((n = read(fd, buff, BUFSIZ)) > 0) { 1395446Slinton write(ofil, buff, n); 1405446Slinton } 141*14742Sthien (void) close(fd); 1425446Slinton } 1435446Slinton 1445446Slinton removenlfile() 1455446Slinton { 1465446Slinton unlink(symname); 1475446Slinton unlink(strname); 1485446Slinton unlink(filesname); 1495446Slinton unlink(linesname); 1505446Slinton } 1515446Slinton 1525655Slinton nlhdrsize() 1535655Slinton { 1545655Slinton int r; 1555655Slinton 1565655Slinton if (!opt('g')) { 1575655Slinton r = 0; 1585655Slinton } else { 1595655Slinton r = nlsize + sizeof(nlhdr); 1605655Slinton } 1615655Slinton return r; 1625655Slinton } 1635655Slinton 1645446Slinton #define isblock(s) (s->class == FUNC || s->class == PROC) 1655446Slinton #define isbuiltin(s) ((s->nl_block&037) == 0 && isblock(s)) 1665446Slinton #define symno(p) (p==NULL ? 0 : nloff(p)) 1675446Slinton 1685446Slinton struct nls { 1695446Slinton struct nl *nls_low; 1705446Slinton struct nl *nls_high; 1715446Slinton }; 1725446Slinton 1735446Slinton struct nl nl[], *nlp, ntab[], *nlact; 1745446Slinton 175*14742Sthien /*VARARGS*/ 1765446Slinton savenl(to, rout) 1775446Slinton struct nl *to; 1785446Slinton { 1795446Slinton register struct nl *p; 1805446Slinton register OBJSYM *s; 1815446Slinton OBJSYM tmpsym; 1825446Slinton struct nls *nlsp; 1835446Slinton 1845446Slinton if (to != NIL) { 185*14742Sthien putblock((char *) rout); 1865446Slinton } else { 1875446Slinton putblock("main program"); 1885446Slinton } 189*14742Sthien nlsp = (struct nls *) nlact; 1905446Slinton s = &tmpsym; 1915446Slinton for (p = nlp; p != to;) { 1925446Slinton if (p == nlsp->nls_low) { 193*14742Sthien if (nlsp == ((struct nls *) &ntab[0])) 1945446Slinton break; 1955446Slinton nlsp--; 1965446Slinton p = nlsp->nls_high; 1975446Slinton } 1985446Slinton p--; 1995446Slinton if (isbuiltin(p) || symno(p) == 0) { 2005446Slinton continue; 2015446Slinton } 2025446Slinton nlhdr.nsyms++; 2035655Slinton nlsize += sizeof(OBJSYM) + sizeof(int); 204*14742Sthien (void) putw(symno(p), symfp); 2055446Slinton if (p->symbol != NULL) { 2065446Slinton s->strindex = nlhdr.stringsize; 2075446Slinton putstring(p->symbol); 2085446Slinton } else { 2095446Slinton s->strindex = 0; 2105446Slinton } 2115446Slinton s->oclass = p->class; 2125446Slinton s->oblkno = (p->nl_block&037); 2135446Slinton s->typno = symno(p->type); 2145446Slinton s->chno = symno(p->chain); 2155446Slinton s->osymvalue.orangev.lower = p->range[0]; 2165446Slinton s->osymvalue.orangev.upper = p->range[1]; 2175446Slinton if (isblock(p)) { 2187919Smckusick s->osymvalue.ofuncv.codeloc = p->value[NL_ENTLOC]; 2195446Slinton } else if (p->class == RECORD || p->class == VARNT) { 2205446Slinton s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]); 2215446Slinton s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]); 2225446Slinton } 223*14742Sthien fwrite((char *) s, sizeof(*s), 1, symfp); 2245446Slinton } 2255446Slinton } 2265446Slinton 2275446Slinton /* 2285446Slinton * Dump a line number and the current object location counter. 2295446Slinton * 2305446Slinton * To save space the difference from the previous line number and offset 2315446Slinton * (one byte each) is dumped. 2325446Slinton */ 2335446Slinton 2345446Slinton LOCAL int oline = 0; 2355655Slinton LOCAL int olc = HEADER_BYTES; 2365446Slinton 2375446Slinton lineno(line) 2385446Slinton int line; 2395446Slinton { 2405755Slinton OBJLINE info; 2415755Slinton 2425446Slinton if (line != oline) { 2435446Slinton nlhdr.nlines++; 2445755Slinton nlsize += sizeof(OBJLINE); 2455755Slinton info.separate.lineincr = line - oline; 246*14742Sthien info.separate.addrincr = ((unsigned short) (lc - olc)); 247*14742Sthien (void) putw((int) info.together, linesfp); 2485446Slinton oline = line; 249*14742Sthien olc = (int) lc; 2505446Slinton } 2515446Slinton } 2525446Slinton 2535446Slinton /* 2545446Slinton * put out a file name entry, including: 2555446Slinton * 2565446Slinton * the current line number for the new file 2575446Slinton * the current location counter 2585446Slinton * the string table address of the file name 2595446Slinton * an index into the current line number information 2605446Slinton */ 2615446Slinton 2625446Slinton newfile(s, line) 2635446Slinton char *s; 2645446Slinton int line; 2655446Slinton { 2665446Slinton FILETAB ft; 2675446Slinton 2685446Slinton nlhdr.nfiles++; 2695655Slinton nlsize += sizeof(FILETAB); 2705446Slinton ft.line = line; 2715446Slinton oline = line; 2725446Slinton if (lc == 0) { 2735446Slinton ft.addr = 0; 2745446Slinton } else { 275*14742Sthien ft.addr = ((LINENO) lc - HEADER_BYTES ); 2765446Slinton } 2775446Slinton ft.filename = (char *) nlhdr.stringsize; 2785446Slinton putstring(s); 2795446Slinton ft.lineindex = nlhdr.nlines; 280*14742Sthien fwrite((char *) (&ft), sizeof(ft), 1, filesfp); 2815446Slinton } 2825446Slinton 2835446Slinton /* 2845446Slinton * put out a dummy symbol at the beginning of a block 2855446Slinton */ 2865446Slinton 2875446Slinton LOCAL putblock(s) 2885446Slinton char *s; 2895446Slinton { 2905446Slinton static OBJSYM zerosym; 2915446Slinton 2925446Slinton nlhdr.nsyms++; 2935655Slinton nlsize += sizeof(OBJSYM) + sizeof(int); 294*14742Sthien (void) putw(0, symfp); 2955446Slinton zerosym.strindex = nlhdr.stringsize; 2965446Slinton putstring(s); 297*14742Sthien fwrite((char *) (&zerosym), sizeof(zerosym), 1, symfp); 2985446Slinton } 2995446Slinton 3005446Slinton /* 3015446Slinton * put out a string to the string table file 3025446Slinton */ 3035446Slinton 3045446Slinton LOCAL putstring(s) 3055446Slinton char *s; 3065446Slinton { 3075446Slinton register char *p; 3085446Slinton 3095655Slinton for (p = s; *p != '\0'; p++) { 3105446Slinton putc(*p, strfp); 3115655Slinton } 3125446Slinton nlhdr.stringsize += (p - s + 1); 3135655Slinton nlsize += (p - s + 1); 3145446Slinton putc('\0', strfp); 3155446Slinton } 3166427Speter #endif OBJ 317