15446Slinton /* Copyright (c) 1982 Regents of the University of California */ 25446Slinton 3*5755Slinton static char sccsid[] = "@(#)savenl.c 1.3 02/11/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" 345446Slinton #include "0.h" 355655Slinton #include "objfmt.h" 365446Slinton 375446Slinton #undef NIL 385446Slinton 395446Slinton /* 405446Slinton * pdx header files 415446Slinton */ 425446Slinton 435446Slinton #include "defs.h" 445446Slinton #include "object.h" 455446Slinton #include "object/objsym.rep" 465446Slinton #include "mappings.h" 475446Slinton #include "mappings/filetab.h" 485446Slinton 495446Slinton LOCAL char *symname = "/tmp/obj.symXXXX"; 505446Slinton LOCAL char *strname = "/tmp/obj.strXXXX"; 515446Slinton LOCAL char *filesname = "/tmp/obj.filesXXXX"; 525446Slinton LOCAL char *linesname = "/tmp/obj.linesXXXX"; 535446Slinton 545446Slinton LOCAL FILE *symfp; 555446Slinton LOCAL FILE *strfp; 565446Slinton LOCAL FILE *filesfp; 575446Slinton LOCAL FILE *linesfp; 585446Slinton 595655Slinton LOCAL long nlsize; 605655Slinton 615446Slinton /* 625446Slinton * create temporary files for the namelist info 635446Slinton */ 645446Slinton 655446Slinton startnlfile() 665446Slinton { 675655Slinton nlsize = 0; 685446Slinton mktemp(symname); 695446Slinton mktemp(strname); 705446Slinton mktemp(filesname); 715446Slinton mktemp(linesname); 725446Slinton symfp = fopen(symname, "w"); 735446Slinton strfp = fopen(strname, "w"); 745446Slinton filesfp = fopen(filesname, "w"); 755446Slinton linesfp = fopen(linesname, "w"); 765446Slinton if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) { 775446Slinton fprintf(stderr, "can't create /tmp/obj"); 785446Slinton pexit(NOSTART); 795446Slinton } 805446Slinton newfile(filename, 1); 815446Slinton } 825446Slinton 835446Slinton /* 845446Slinton * now copy the temp files back to obj; strings, symbols, file names, and lines 855446Slinton * 865446Slinton * There's some efficiency garbage here that uses straight system 875446Slinton * calls rather than standard I/O library calls. 885446Slinton */ 895446Slinton 905446Slinton copynlfile() 915446Slinton { 925446Slinton register int n; 935446Slinton int symfd, strfd, filesfd, linesfd; 945446Slinton char buff[BUFSIZ]; 955446Slinton 965446Slinton fclose(symfp); 975446Slinton fclose(strfp); 985446Slinton fclose(filesfp); 995446Slinton fclose(linesfp); 1005655Slinton if (!opt('g')) { 1015655Slinton removenlfile(); 1025655Slinton return; 1035655Slinton } 1045446Slinton symfd = open(symname, 0); 1055446Slinton strfd = open(strname, 0); 1065446Slinton filesfd = open(filesname, 0); 1075446Slinton linesfd = open(linesname, 0); 1085446Slinton if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) { 1095446Slinton fprintf(stderr, "sync error on /tmp/obj"); 1105446Slinton pexit(ERRS); 1115446Slinton } 1125446Slinton lseek(ofil, 0L, 2); 1135446Slinton write(ofil, &nlhdr, sizeof(nlhdr)); 1145446Slinton n = read(strfd, buff, BUFSIZ - sizeof(nlhdr)); 1155446Slinton write(ofil, buff, n); 1165446Slinton cat(strfd); 1175446Slinton cat(symfd); 1185446Slinton cat(filesfd); 1195446Slinton cat(linesfd); 1205446Slinton removenlfile(); 1215446Slinton } 1225446Slinton 1235446Slinton cat(fd) 1245446Slinton int fd; 1255446Slinton { 1265446Slinton register int n; 1275446Slinton char buff[BUFSIZ]; 1285446Slinton 1295446Slinton while ((n = read(fd, buff, BUFSIZ)) > 0) { 1305446Slinton write(ofil, buff, n); 1315446Slinton } 1325446Slinton close(fd); 1335446Slinton } 1345446Slinton 1355446Slinton removenlfile() 1365446Slinton { 1375446Slinton unlink(symname); 1385446Slinton unlink(strname); 1395446Slinton unlink(filesname); 1405446Slinton unlink(linesname); 1415446Slinton } 1425446Slinton 1435655Slinton nlhdrsize() 1445655Slinton { 1455655Slinton int r; 1465655Slinton 1475655Slinton if (!opt('g')) { 1485655Slinton r = 0; 1495655Slinton } else { 1505655Slinton r = nlsize + sizeof(nlhdr); 1515655Slinton } 1525655Slinton return r; 1535655Slinton } 1545655Slinton 1555446Slinton #define isblock(s) (s->class == FUNC || s->class == PROC) 1565446Slinton #define isbuiltin(s) ((s->nl_block&037) == 0 && isblock(s)) 1575446Slinton #define symno(p) (p==NULL ? 0 : nloff(p)) 1585446Slinton 1595446Slinton struct nls { 1605446Slinton struct nl *nls_low; 1615446Slinton struct nl *nls_high; 1625446Slinton }; 1635446Slinton 1645446Slinton struct nl nl[], *nlp, ntab[], *nlact; 1655446Slinton 1665446Slinton savenl(to, rout) 1675446Slinton struct nl *to; 1685446Slinton { 1695446Slinton register struct nl *p; 1705446Slinton register OBJSYM *s; 1715446Slinton OBJSYM tmpsym; 1725446Slinton struct nls *nlsp; 1735446Slinton int v; 1745446Slinton 1755446Slinton if (to != NIL) { 1765446Slinton putblock(rout); 1775446Slinton } else { 1785446Slinton putblock("main program"); 1795446Slinton } 1805446Slinton nlsp = nlact; 1815446Slinton s = &tmpsym; 1825446Slinton for (p = nlp; p != to;) { 1835446Slinton if (p == nlsp->nls_low) { 1845446Slinton if (nlsp == &ntab[0]) 1855446Slinton break; 1865446Slinton nlsp--; 1875446Slinton p = nlsp->nls_high; 1885446Slinton } 1895446Slinton p--; 1905446Slinton if (isbuiltin(p) || symno(p) == 0) { 1915446Slinton continue; 1925446Slinton } 1935446Slinton nlhdr.nsyms++; 1945655Slinton nlsize += sizeof(OBJSYM) + sizeof(int); 1955446Slinton putw(symno(p), symfp); 1965446Slinton if (p->symbol != NULL) { 1975446Slinton s->strindex = nlhdr.stringsize; 1985446Slinton putstring(p->symbol); 1995446Slinton } else { 2005446Slinton s->strindex = 0; 2015446Slinton } 2025446Slinton s->oclass = p->class; 2035446Slinton s->oblkno = (p->nl_block&037); 2045446Slinton s->typno = symno(p->type); 2055446Slinton s->chno = symno(p->chain); 2065446Slinton s->osymvalue.orangev.lower = p->range[0]; 2075446Slinton s->osymvalue.orangev.upper = p->range[1]; 2085446Slinton if (isblock(p)) { 2095446Slinton s->osymvalue.ofuncv.codeloc = p->entloc; 2105446Slinton } else if (p->class == RECORD || p->class == VARNT) { 2115446Slinton s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]); 2125446Slinton s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]); 2135446Slinton } 2145446Slinton fwrite(s, sizeof(*s), 1, symfp); 2155446Slinton } 2165446Slinton } 2175446Slinton 2185446Slinton /* 2195446Slinton * Dump a line number and the current object location counter. 2205446Slinton * 2215446Slinton * To save space the difference from the previous line number and offset 2225446Slinton * (one byte each) is dumped. 2235446Slinton */ 2245446Slinton 2255446Slinton LOCAL int oline = 0; 2265655Slinton LOCAL int olc = HEADER_BYTES; 2275446Slinton 2285446Slinton lineno(line) 2295446Slinton int line; 2305446Slinton { 231*5755Slinton OBJLINE info; 232*5755Slinton 2335446Slinton if (line != oline) { 2345446Slinton nlhdr.nlines++; 235*5755Slinton nlsize += sizeof(OBJLINE); 236*5755Slinton info.separate.lineincr = line - oline; 237*5755Slinton info.separate.addrincr = lc - olc; 238*5755Slinton putw(info.together, linesfp); 2395446Slinton oline = line; 2405446Slinton olc = lc; 2415446Slinton } 2425446Slinton } 2435446Slinton 2445446Slinton /* 2455446Slinton * put out a file name entry, including: 2465446Slinton * 2475446Slinton * the current line number for the new file 2485446Slinton * the current location counter 2495446Slinton * the string table address of the file name 2505446Slinton * an index into the current line number information 2515446Slinton */ 2525446Slinton 2535446Slinton newfile(s, line) 2545446Slinton char *s; 2555446Slinton int line; 2565446Slinton { 2575446Slinton FILETAB ft; 2585446Slinton 2595446Slinton nlhdr.nfiles++; 2605655Slinton nlsize += sizeof(FILETAB); 2615446Slinton ft.line = line; 2625446Slinton oline = line; 2635446Slinton if (lc == 0) { 2645446Slinton ft.addr = 0; 2655446Slinton } else { 2665655Slinton ft.addr = lc - HEADER_BYTES; 2675446Slinton } 2685446Slinton ft.filename = (char *) nlhdr.stringsize; 2695446Slinton putstring(s); 2705446Slinton ft.lineindex = nlhdr.nlines; 2715446Slinton fwrite(&ft, sizeof(ft), 1, filesfp); 2725446Slinton } 2735446Slinton 2745446Slinton /* 2755446Slinton * put out a dummy symbol at the beginning of a block 2765446Slinton */ 2775446Slinton 2785446Slinton LOCAL putblock(s) 2795446Slinton char *s; 2805446Slinton { 2815446Slinton register int i; 2825446Slinton static OBJSYM zerosym; 2835446Slinton 2845446Slinton nlhdr.nsyms++; 2855655Slinton nlsize += sizeof(OBJSYM) + sizeof(int); 2865446Slinton putw(0, symfp); 2875446Slinton zerosym.strindex = nlhdr.stringsize; 2885446Slinton putstring(s); 2895446Slinton fwrite(&zerosym, sizeof(zerosym), 1, symfp); 2905446Slinton } 2915446Slinton 2925446Slinton /* 2935446Slinton * put out a string to the string table file 2945446Slinton */ 2955446Slinton 2965446Slinton LOCAL putstring(s) 2975446Slinton char *s; 2985446Slinton { 2995446Slinton register char *p; 3005446Slinton 3015655Slinton for (p = s; *p != '\0'; p++) { 3025446Slinton putc(*p, strfp); 3035655Slinton } 3045446Slinton nlhdr.stringsize += (p - s + 1); 3055655Slinton nlsize += (p - s + 1); 3065446Slinton putc('\0', strfp); 3075446Slinton } 308