15446Slinton /* Copyright (c) 1982 Regents of the University of California */ 25446Slinton 3*6427Speter static char sccsid[] = "@(#)savenl.c 1.4 04/01/82"; 45446Slinton 55446Slinton /* 65446Slinton * savenl - routines for saving namelist and line number information 75446Slinton * 85446Slinton * This module contains the routines that make pi dump a namelist 95446Slinton * at the end of the object file. We do this by first creating 105446Slinton * four temporary files in "startnlfile". One temp file contains 115446Slinton * the string table, one the symbol table, one the file name 125446Slinton * information and one the line number information. 135446Slinton * 145446Slinton * Prior to generation of the code for a statement the "lineno" 155446Slinton * routine is called to dump the line number and current object 165446Slinton * address. At the end of each block "savenl" is called to dump 175446Slinton * the strings and symbol structures. 185446Slinton * 195446Slinton * At the end of execution "copynlfile" is called and it copies 205446Slinton * the temp files onto the end of the obj file. 215446Slinton * 225446Slinton * In case of error, "removenlfile" is called to destroy the temp files. 235446Slinton * 245446Slinton * The only other changes to pi are in calling these routines from 255446Slinton * 265446Slinton * "main" (main.c) 275446Slinton * "yymain" (yymain.c) 285446Slinton * "funcend" (fend.c) 295446Slinton * "yyget" (yyget.c) 305446Slinton * "putline" (stat.c) 315446Slinton */ 325446Slinton 335446Slinton #include "whoami.h" 34*6427Speter #ifdef OBJ 35*6427Speter /* 36*6427Speter * and the rest of the file 37*6427Speter */ 385446Slinton #include "0.h" 395655Slinton #include "objfmt.h" 405446Slinton 415446Slinton #undef NIL 425446Slinton 435446Slinton /* 445446Slinton * pdx header files 455446Slinton */ 465446Slinton 47*6427Speter #include "../pdx/defs.h" 48*6427Speter #include "../pdx/object.h" 49*6427Speter #include "../pdx/object/objsym.rep" 50*6427Speter #include "../pdx/mappings.h" 51*6427Speter #include "../pdx/mappings/filetab.h" 525446Slinton 535446Slinton LOCAL char *symname = "/tmp/obj.symXXXX"; 545446Slinton LOCAL char *strname = "/tmp/obj.strXXXX"; 555446Slinton LOCAL char *filesname = "/tmp/obj.filesXXXX"; 565446Slinton LOCAL char *linesname = "/tmp/obj.linesXXXX"; 575446Slinton 585446Slinton LOCAL FILE *symfp; 595446Slinton LOCAL FILE *strfp; 605446Slinton LOCAL FILE *filesfp; 615446Slinton LOCAL FILE *linesfp; 625446Slinton 635655Slinton LOCAL long nlsize; 645655Slinton 655446Slinton /* 665446Slinton * create temporary files for the namelist info 675446Slinton */ 685446Slinton 695446Slinton startnlfile() 705446Slinton { 715655Slinton nlsize = 0; 725446Slinton mktemp(symname); 735446Slinton mktemp(strname); 745446Slinton mktemp(filesname); 755446Slinton mktemp(linesname); 765446Slinton symfp = fopen(symname, "w"); 775446Slinton strfp = fopen(strname, "w"); 785446Slinton filesfp = fopen(filesname, "w"); 795446Slinton linesfp = fopen(linesname, "w"); 805446Slinton if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) { 815446Slinton fprintf(stderr, "can't create /tmp/obj"); 825446Slinton pexit(NOSTART); 835446Slinton } 845446Slinton newfile(filename, 1); 855446Slinton } 865446Slinton 875446Slinton /* 885446Slinton * now copy the temp files back to obj; strings, symbols, file names, and lines 895446Slinton * 905446Slinton * There's some efficiency garbage here that uses straight system 915446Slinton * calls rather than standard I/O library calls. 925446Slinton */ 935446Slinton 945446Slinton copynlfile() 955446Slinton { 965446Slinton register int n; 975446Slinton int symfd, strfd, filesfd, linesfd; 985446Slinton char buff[BUFSIZ]; 995446Slinton 1005446Slinton fclose(symfp); 1015446Slinton fclose(strfp); 1025446Slinton fclose(filesfp); 1035446Slinton fclose(linesfp); 1045655Slinton if (!opt('g')) { 1055655Slinton removenlfile(); 1065655Slinton return; 1075655Slinton } 1085446Slinton symfd = open(symname, 0); 1095446Slinton strfd = open(strname, 0); 1105446Slinton filesfd = open(filesname, 0); 1115446Slinton linesfd = open(linesname, 0); 1125446Slinton if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) { 1135446Slinton fprintf(stderr, "sync error on /tmp/obj"); 1145446Slinton pexit(ERRS); 1155446Slinton } 1165446Slinton lseek(ofil, 0L, 2); 1175446Slinton write(ofil, &nlhdr, sizeof(nlhdr)); 1185446Slinton n = read(strfd, buff, BUFSIZ - sizeof(nlhdr)); 1195446Slinton write(ofil, buff, n); 1205446Slinton cat(strfd); 1215446Slinton cat(symfd); 1225446Slinton cat(filesfd); 1235446Slinton cat(linesfd); 1245446Slinton removenlfile(); 1255446Slinton } 1265446Slinton 1275446Slinton cat(fd) 1285446Slinton int fd; 1295446Slinton { 1305446Slinton register int n; 1315446Slinton char buff[BUFSIZ]; 1325446Slinton 1335446Slinton while ((n = read(fd, buff, BUFSIZ)) > 0) { 1345446Slinton write(ofil, buff, n); 1355446Slinton } 1365446Slinton close(fd); 1375446Slinton } 1385446Slinton 1395446Slinton removenlfile() 1405446Slinton { 1415446Slinton unlink(symname); 1425446Slinton unlink(strname); 1435446Slinton unlink(filesname); 1445446Slinton unlink(linesname); 1455446Slinton } 1465446Slinton 1475655Slinton nlhdrsize() 1485655Slinton { 1495655Slinton int r; 1505655Slinton 1515655Slinton if (!opt('g')) { 1525655Slinton r = 0; 1535655Slinton } else { 1545655Slinton r = nlsize + sizeof(nlhdr); 1555655Slinton } 1565655Slinton return r; 1575655Slinton } 1585655Slinton 1595446Slinton #define isblock(s) (s->class == FUNC || s->class == PROC) 1605446Slinton #define isbuiltin(s) ((s->nl_block&037) == 0 && isblock(s)) 1615446Slinton #define symno(p) (p==NULL ? 0 : nloff(p)) 1625446Slinton 1635446Slinton struct nls { 1645446Slinton struct nl *nls_low; 1655446Slinton struct nl *nls_high; 1665446Slinton }; 1675446Slinton 1685446Slinton struct nl nl[], *nlp, ntab[], *nlact; 1695446Slinton 1705446Slinton savenl(to, rout) 1715446Slinton struct nl *to; 1725446Slinton { 1735446Slinton register struct nl *p; 1745446Slinton register OBJSYM *s; 1755446Slinton OBJSYM tmpsym; 1765446Slinton struct nls *nlsp; 1775446Slinton int v; 1785446Slinton 1795446Slinton if (to != NIL) { 1805446Slinton putblock(rout); 1815446Slinton } else { 1825446Slinton putblock("main program"); 1835446Slinton } 1845446Slinton nlsp = nlact; 1855446Slinton s = &tmpsym; 1865446Slinton for (p = nlp; p != to;) { 1875446Slinton if (p == nlsp->nls_low) { 1885446Slinton if (nlsp == &ntab[0]) 1895446Slinton break; 1905446Slinton nlsp--; 1915446Slinton p = nlsp->nls_high; 1925446Slinton } 1935446Slinton p--; 1945446Slinton if (isbuiltin(p) || symno(p) == 0) { 1955446Slinton continue; 1965446Slinton } 1975446Slinton nlhdr.nsyms++; 1985655Slinton nlsize += sizeof(OBJSYM) + sizeof(int); 1995446Slinton putw(symno(p), symfp); 2005446Slinton if (p->symbol != NULL) { 2015446Slinton s->strindex = nlhdr.stringsize; 2025446Slinton putstring(p->symbol); 2035446Slinton } else { 2045446Slinton s->strindex = 0; 2055446Slinton } 2065446Slinton s->oclass = p->class; 2075446Slinton s->oblkno = (p->nl_block&037); 2085446Slinton s->typno = symno(p->type); 2095446Slinton s->chno = symno(p->chain); 2105446Slinton s->osymvalue.orangev.lower = p->range[0]; 2115446Slinton s->osymvalue.orangev.upper = p->range[1]; 2125446Slinton if (isblock(p)) { 2135446Slinton s->osymvalue.ofuncv.codeloc = p->entloc; 2145446Slinton } else if (p->class == RECORD || p->class == VARNT) { 2155446Slinton s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]); 2165446Slinton s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]); 2175446Slinton } 2185446Slinton fwrite(s, sizeof(*s), 1, symfp); 2195446Slinton } 2205446Slinton } 2215446Slinton 2225446Slinton /* 2235446Slinton * Dump a line number and the current object location counter. 2245446Slinton * 2255446Slinton * To save space the difference from the previous line number and offset 2265446Slinton * (one byte each) is dumped. 2275446Slinton */ 2285446Slinton 2295446Slinton LOCAL int oline = 0; 2305655Slinton LOCAL int olc = HEADER_BYTES; 2315446Slinton 2325446Slinton lineno(line) 2335446Slinton int line; 2345446Slinton { 2355755Slinton OBJLINE info; 2365755Slinton 2375446Slinton if (line != oline) { 2385446Slinton nlhdr.nlines++; 2395755Slinton nlsize += sizeof(OBJLINE); 2405755Slinton info.separate.lineincr = line - oline; 2415755Slinton info.separate.addrincr = lc - olc; 2425755Slinton putw(info.together, linesfp); 2435446Slinton oline = line; 2445446Slinton olc = lc; 2455446Slinton } 2465446Slinton } 2475446Slinton 2485446Slinton /* 2495446Slinton * put out a file name entry, including: 2505446Slinton * 2515446Slinton * the current line number for the new file 2525446Slinton * the current location counter 2535446Slinton * the string table address of the file name 2545446Slinton * an index into the current line number information 2555446Slinton */ 2565446Slinton 2575446Slinton newfile(s, line) 2585446Slinton char *s; 2595446Slinton int line; 2605446Slinton { 2615446Slinton FILETAB ft; 2625446Slinton 2635446Slinton nlhdr.nfiles++; 2645655Slinton nlsize += sizeof(FILETAB); 2655446Slinton ft.line = line; 2665446Slinton oline = line; 2675446Slinton if (lc == 0) { 2685446Slinton ft.addr = 0; 2695446Slinton } else { 2705655Slinton ft.addr = lc - HEADER_BYTES; 2715446Slinton } 2725446Slinton ft.filename = (char *) nlhdr.stringsize; 2735446Slinton putstring(s); 2745446Slinton ft.lineindex = nlhdr.nlines; 2755446Slinton fwrite(&ft, sizeof(ft), 1, filesfp); 2765446Slinton } 2775446Slinton 2785446Slinton /* 2795446Slinton * put out a dummy symbol at the beginning of a block 2805446Slinton */ 2815446Slinton 2825446Slinton LOCAL putblock(s) 2835446Slinton char *s; 2845446Slinton { 2855446Slinton register int i; 2865446Slinton static OBJSYM zerosym; 2875446Slinton 2885446Slinton nlhdr.nsyms++; 2895655Slinton nlsize += sizeof(OBJSYM) + sizeof(int); 2905446Slinton putw(0, symfp); 2915446Slinton zerosym.strindex = nlhdr.stringsize; 2925446Slinton putstring(s); 2935446Slinton fwrite(&zerosym, sizeof(zerosym), 1, symfp); 2945446Slinton } 2955446Slinton 2965446Slinton /* 2975446Slinton * put out a string to the string table file 2985446Slinton */ 2995446Slinton 3005446Slinton LOCAL putstring(s) 3015446Slinton char *s; 3025446Slinton { 3035446Slinton register char *p; 3045446Slinton 3055655Slinton for (p = s; *p != '\0'; p++) { 3065446Slinton putc(*p, strfp); 3075655Slinton } 3085446Slinton nlhdr.stringsize += (p - s + 1); 3095655Slinton nlsize += (p - s + 1); 3105446Slinton putc('\0', strfp); 3115446Slinton } 312*6427Speter #endif OBJ 313