1*22189Sdist /* 2*22189Sdist * Copyright (c) 1980 Regents of the University of California. 3*22189Sdist * All rights reserved. The Berkeley software License Agreement 4*22189Sdist * specifies the terms and conditions for redistribution. 5*22189Sdist */ 65446Slinton 714742Sthien #ifndef lint 8*22189Sdist static char sccsid[] = "@(#)savenl.c 5.1 (Berkeley) 06/05/85"; 9*22189Sdist #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 595446Slinton LOCAL char *symname = "/tmp/obj.symXXXX"; 605446Slinton LOCAL char *strname = "/tmp/obj.strXXXX"; 615446Slinton LOCAL char *filesname = "/tmp/obj.filesXXXX"; 625446Slinton LOCAL char *linesname = "/tmp/obj.linesXXXX"; 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 735446Slinton /* 745446Slinton * create temporary files for the namelist info 755446Slinton */ 765446Slinton 775446Slinton startnlfile() 785446Slinton { 795655Slinton nlsize = 0; 8014742Sthien (void) mktemp(symname); 8114742Sthien (void) mktemp(strname); 8214742Sthien (void) mktemp(filesname); 8314742Sthien (void) mktemp(linesname); 845446Slinton symfp = fopen(symname, "w"); 855446Slinton strfp = fopen(strname, "w"); 865446Slinton filesfp = fopen(filesname, "w"); 875446Slinton linesfp = fopen(linesname, "w"); 885446Slinton if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) { 895446Slinton fprintf(stderr, "can't create /tmp/obj"); 905446Slinton pexit(NOSTART); 915446Slinton } 925446Slinton newfile(filename, 1); 935446Slinton } 945446Slinton 955446Slinton /* 965446Slinton * now copy the temp files back to obj; strings, symbols, file names, and lines 975446Slinton * 985446Slinton * There's some efficiency garbage here that uses straight system 995446Slinton * calls rather than standard I/O library calls. 1005446Slinton */ 1015446Slinton 1025446Slinton copynlfile() 1035446Slinton { 1045446Slinton register int n; 10514742Sthien extern long lseek(); 1065446Slinton int symfd, strfd, filesfd, linesfd; 1075446Slinton char buff[BUFSIZ]; 1085446Slinton 10914742Sthien (void) fclose((FILE *) symfp); 11014742Sthien (void) fclose((FILE *) strfp); 11114742Sthien (void) fclose((FILE *) filesfp); 11214742Sthien (void) fclose((FILE *) linesfp); 1135655Slinton if (!opt('g')) { 1145655Slinton removenlfile(); 1155655Slinton return; 1165655Slinton } 1175446Slinton symfd = open(symname, 0); 1185446Slinton strfd = open(strname, 0); 1195446Slinton filesfd = open(filesname, 0); 1205446Slinton linesfd = open(linesname, 0); 1215446Slinton if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) { 1225446Slinton fprintf(stderr, "sync error on /tmp/obj"); 1235446Slinton pexit(ERRS); 1245446Slinton } 12514742Sthien (void) lseek(ofil, 0L, 2); 12614742Sthien write(ofil, (char *) (&nlhdr), sizeof(nlhdr)); 1275446Slinton n = read(strfd, buff, BUFSIZ - sizeof(nlhdr)); 1285446Slinton write(ofil, buff, n); 1295446Slinton cat(strfd); 1305446Slinton cat(symfd); 1315446Slinton cat(filesfd); 1325446Slinton cat(linesfd); 1335446Slinton removenlfile(); 1345446Slinton } 1355446Slinton 1365446Slinton cat(fd) 1375446Slinton int fd; 1385446Slinton { 1395446Slinton register int n; 1405446Slinton char buff[BUFSIZ]; 1415446Slinton 1425446Slinton while ((n = read(fd, buff, BUFSIZ)) > 0) { 1435446Slinton write(ofil, buff, n); 1445446Slinton } 14514742Sthien (void) close(fd); 1465446Slinton } 1475446Slinton 1485446Slinton removenlfile() 1495446Slinton { 1505446Slinton unlink(symname); 1515446Slinton unlink(strname); 1525446Slinton unlink(filesname); 1535446Slinton unlink(linesname); 1545446Slinton } 1555446Slinton 1565655Slinton nlhdrsize() 1575655Slinton { 1585655Slinton int r; 1595655Slinton 1605655Slinton if (!opt('g')) { 1615655Slinton r = 0; 1625655Slinton } else { 1635655Slinton r = nlsize + sizeof(nlhdr); 1645655Slinton } 1655655Slinton return r; 1665655Slinton } 1675655Slinton 1685446Slinton #define isblock(s) (s->class == FUNC || s->class == PROC) 1695446Slinton #define isbuiltin(s) ((s->nl_block&037) == 0 && isblock(s)) 1705446Slinton #define symno(p) (p==NULL ? 0 : nloff(p)) 1715446Slinton 1725446Slinton struct nls { 1735446Slinton struct nl *nls_low; 1745446Slinton struct nl *nls_high; 1755446Slinton }; 1765446Slinton 1775446Slinton struct nl nl[], *nlp, ntab[], *nlact; 1785446Slinton 17914742Sthien /*VARARGS*/ 1805446Slinton savenl(to, rout) 1815446Slinton struct nl *to; 1825446Slinton { 1835446Slinton register struct nl *p; 1845446Slinton register OBJSYM *s; 1855446Slinton OBJSYM tmpsym; 1865446Slinton struct nls *nlsp; 1875446Slinton 1885446Slinton if (to != NIL) { 18914742Sthien putblock((char *) rout); 1905446Slinton } else { 1915446Slinton putblock("main program"); 1925446Slinton } 19314742Sthien nlsp = (struct nls *) nlact; 1945446Slinton s = &tmpsym; 1955446Slinton for (p = nlp; p != to;) { 1965446Slinton if (p == nlsp->nls_low) { 19714742Sthien if (nlsp == ((struct nls *) &ntab[0])) 1985446Slinton break; 1995446Slinton nlsp--; 2005446Slinton p = nlsp->nls_high; 2015446Slinton } 2025446Slinton p--; 2035446Slinton if (isbuiltin(p) || symno(p) == 0) { 2045446Slinton continue; 2055446Slinton } 2065446Slinton nlhdr.nsyms++; 2075655Slinton nlsize += sizeof(OBJSYM) + sizeof(int); 20814742Sthien (void) putw(symno(p), symfp); 2095446Slinton if (p->symbol != NULL) { 2105446Slinton s->strindex = nlhdr.stringsize; 2115446Slinton putstring(p->symbol); 2125446Slinton } else { 2135446Slinton s->strindex = 0; 2145446Slinton } 2155446Slinton s->oclass = p->class; 2165446Slinton s->oblkno = (p->nl_block&037); 2175446Slinton s->typno = symno(p->type); 2185446Slinton s->chno = symno(p->chain); 2195446Slinton s->osymvalue.orangev.lower = p->range[0]; 2205446Slinton s->osymvalue.orangev.upper = p->range[1]; 2215446Slinton if (isblock(p)) { 2227919Smckusick s->osymvalue.ofuncv.codeloc = p->value[NL_ENTLOC]; 2235446Slinton } else if (p->class == RECORD || p->class == VARNT) { 2245446Slinton s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]); 2255446Slinton s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]); 2265446Slinton } 22714742Sthien fwrite((char *) s, sizeof(*s), 1, symfp); 2285446Slinton } 2295446Slinton } 2305446Slinton 2315446Slinton /* 2325446Slinton * Dump a line number and the current object location counter. 2335446Slinton * 2345446Slinton * To save space the difference from the previous line number and offset 2355446Slinton * (one byte each) is dumped. 2365446Slinton */ 2375446Slinton 2385446Slinton LOCAL int oline = 0; 2395655Slinton LOCAL int olc = HEADER_BYTES; 2405446Slinton 2415446Slinton lineno(line) 2425446Slinton int line; 2435446Slinton { 2445755Slinton OBJLINE info; 2455755Slinton 2465446Slinton if (line != oline) { 2475446Slinton nlhdr.nlines++; 2485755Slinton nlsize += sizeof(OBJLINE); 2495755Slinton info.separate.lineincr = line - oline; 25014742Sthien info.separate.addrincr = ((unsigned short) (lc - olc)); 25114742Sthien (void) putw((int) info.together, linesfp); 2525446Slinton oline = line; 25314742Sthien olc = (int) lc; 2545446Slinton } 2555446Slinton } 2565446Slinton 2575446Slinton /* 2585446Slinton * put out a file name entry, including: 2595446Slinton * 2605446Slinton * the current line number for the new file 2615446Slinton * the current location counter 2625446Slinton * the string table address of the file name 2635446Slinton * an index into the current line number information 2645446Slinton */ 2655446Slinton 2665446Slinton newfile(s, line) 2675446Slinton char *s; 2685446Slinton int line; 2695446Slinton { 2705446Slinton FILETAB ft; 2715446Slinton 2725446Slinton nlhdr.nfiles++; 2735655Slinton nlsize += sizeof(FILETAB); 2745446Slinton ft.line = line; 2755446Slinton oline = line; 2765446Slinton if (lc == 0) { 2775446Slinton ft.addr = 0; 2785446Slinton } else { 27914742Sthien ft.addr = ((LINENO) lc - HEADER_BYTES ); 2805446Slinton } 2815446Slinton ft.filename = (char *) nlhdr.stringsize; 2825446Slinton putstring(s); 2835446Slinton ft.lineindex = nlhdr.nlines; 28414742Sthien fwrite((char *) (&ft), sizeof(ft), 1, filesfp); 2855446Slinton } 2865446Slinton 2875446Slinton /* 2885446Slinton * put out a dummy symbol at the beginning of a block 2895446Slinton */ 2905446Slinton 2915446Slinton LOCAL putblock(s) 2925446Slinton char *s; 2935446Slinton { 2945446Slinton static OBJSYM zerosym; 2955446Slinton 2965446Slinton nlhdr.nsyms++; 2975655Slinton nlsize += sizeof(OBJSYM) + sizeof(int); 29814742Sthien (void) putw(0, symfp); 2995446Slinton zerosym.strindex = nlhdr.stringsize; 3005446Slinton putstring(s); 30114742Sthien fwrite((char *) (&zerosym), sizeof(zerosym), 1, symfp); 3025446Slinton } 3035446Slinton 3045446Slinton /* 3055446Slinton * put out a string to the string table file 3065446Slinton */ 3075446Slinton 3085446Slinton LOCAL putstring(s) 3095446Slinton char *s; 3105446Slinton { 3115446Slinton register char *p; 3125446Slinton 3135655Slinton for (p = s; *p != '\0'; p++) { 3145446Slinton putc(*p, strfp); 3155655Slinton } 3165446Slinton nlhdr.stringsize += (p - s + 1); 3175655Slinton nlsize += (p - s + 1); 3185446Slinton putc('\0', strfp); 3195446Slinton } 3206427Speter #endif OBJ 321