1*5446Slinton /* Copyright (c) 1982 Regents of the University of California */ 2*5446Slinton 3*5446Slinton static char sccsid[] = "@(#)savenl.c 1.1 01/18/82"; 4*5446Slinton 5*5446Slinton /* 6*5446Slinton * savenl - routines for saving namelist and line number information 7*5446Slinton * 8*5446Slinton * This module contains the routines that make pi dump a namelist 9*5446Slinton * at the end of the object file. We do this by first creating 10*5446Slinton * four temporary files in "startnlfile". One temp file contains 11*5446Slinton * the string table, one the symbol table, one the file name 12*5446Slinton * information and one the line number information. 13*5446Slinton * 14*5446Slinton * Prior to generation of the code for a statement the "lineno" 15*5446Slinton * routine is called to dump the line number and current object 16*5446Slinton * address. At the end of each block "savenl" is called to dump 17*5446Slinton * the strings and symbol structures. 18*5446Slinton * 19*5446Slinton * At the end of execution "copynlfile" is called and it copies 20*5446Slinton * the temp files onto the end of the obj file. 21*5446Slinton * 22*5446Slinton * In case of error, "removenlfile" is called to destroy the temp files. 23*5446Slinton * 24*5446Slinton * The only other changes to pi are in calling these routines from 25*5446Slinton * 26*5446Slinton * "main" (main.c) 27*5446Slinton * "yymain" (yymain.c) 28*5446Slinton * "funcend" (fend.c) 29*5446Slinton * "yyget" (yyget.c) 30*5446Slinton * "putline" (stat.c) 31*5446Slinton */ 32*5446Slinton 33*5446Slinton #include "whoami.h" 34*5446Slinton #include "0.h" 35*5446Slinton 36*5446Slinton #undef NIL 37*5446Slinton 38*5446Slinton /* 39*5446Slinton * pdx header files 40*5446Slinton */ 41*5446Slinton 42*5446Slinton #include "defs.h" 43*5446Slinton #include "object.h" 44*5446Slinton #include "object/objsym.rep" 45*5446Slinton #include "mappings.h" 46*5446Slinton #include "mappings/filetab.h" 47*5446Slinton 48*5446Slinton LOCAL char *symname = "/tmp/obj.symXXXX"; 49*5446Slinton LOCAL char *strname = "/tmp/obj.strXXXX"; 50*5446Slinton LOCAL char *filesname = "/tmp/obj.filesXXXX"; 51*5446Slinton LOCAL char *linesname = "/tmp/obj.linesXXXX"; 52*5446Slinton 53*5446Slinton LOCAL FILE *symfp; 54*5446Slinton LOCAL FILE *strfp; 55*5446Slinton LOCAL FILE *filesfp; 56*5446Slinton LOCAL FILE *linesfp; 57*5446Slinton 58*5446Slinton /* 59*5446Slinton * create temporary files for the namelist info 60*5446Slinton */ 61*5446Slinton 62*5446Slinton startnlfile() 63*5446Slinton { 64*5446Slinton mktemp(symname); 65*5446Slinton mktemp(strname); 66*5446Slinton mktemp(filesname); 67*5446Slinton mktemp(linesname); 68*5446Slinton symfp = fopen(symname, "w"); 69*5446Slinton strfp = fopen(strname, "w"); 70*5446Slinton filesfp = fopen(filesname, "w"); 71*5446Slinton linesfp = fopen(linesname, "w"); 72*5446Slinton if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) { 73*5446Slinton fprintf(stderr, "can't create /tmp/obj"); 74*5446Slinton pexit(NOSTART); 75*5446Slinton } 76*5446Slinton newfile(filename, 1); 77*5446Slinton } 78*5446Slinton 79*5446Slinton /* 80*5446Slinton * now copy the temp files back to obj; strings, symbols, file names, and lines 81*5446Slinton * 82*5446Slinton * There's some efficiency garbage here that uses straight system 83*5446Slinton * calls rather than standard I/O library calls. 84*5446Slinton */ 85*5446Slinton 86*5446Slinton copynlfile() 87*5446Slinton { 88*5446Slinton register int n; 89*5446Slinton int symfd, strfd, filesfd, linesfd; 90*5446Slinton char buff[BUFSIZ]; 91*5446Slinton 92*5446Slinton fclose(symfp); 93*5446Slinton fclose(strfp); 94*5446Slinton fclose(filesfp); 95*5446Slinton fclose(linesfp); 96*5446Slinton symfd = open(symname, 0); 97*5446Slinton strfd = open(strname, 0); 98*5446Slinton filesfd = open(filesname, 0); 99*5446Slinton linesfd = open(linesname, 0); 100*5446Slinton if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) { 101*5446Slinton fprintf(stderr, "sync error on /tmp/obj"); 102*5446Slinton pexit(ERRS); 103*5446Slinton } 104*5446Slinton lseek(ofil, 0L, 2); 105*5446Slinton write(ofil, &nlhdr, sizeof(nlhdr)); 106*5446Slinton n = read(strfd, buff, BUFSIZ - sizeof(nlhdr)); 107*5446Slinton write(ofil, buff, n); 108*5446Slinton cat(strfd); 109*5446Slinton cat(symfd); 110*5446Slinton cat(filesfd); 111*5446Slinton cat(linesfd); 112*5446Slinton removenlfile(); 113*5446Slinton } 114*5446Slinton 115*5446Slinton cat(fd) 116*5446Slinton int fd; 117*5446Slinton { 118*5446Slinton register int n; 119*5446Slinton char buff[BUFSIZ]; 120*5446Slinton 121*5446Slinton while ((n = read(fd, buff, BUFSIZ)) > 0) { 122*5446Slinton write(ofil, buff, n); 123*5446Slinton } 124*5446Slinton close(fd); 125*5446Slinton } 126*5446Slinton 127*5446Slinton removenlfile() 128*5446Slinton { 129*5446Slinton unlink(symname); 130*5446Slinton unlink(strname); 131*5446Slinton unlink(filesname); 132*5446Slinton unlink(linesname); 133*5446Slinton } 134*5446Slinton 135*5446Slinton #define isblock(s) (s->class == FUNC || s->class == PROC) 136*5446Slinton #define isbuiltin(s) ((s->nl_block&037) == 0 && isblock(s)) 137*5446Slinton #define symno(p) (p==NULL ? 0 : nloff(p)) 138*5446Slinton 139*5446Slinton struct nls { 140*5446Slinton struct nl *nls_low; 141*5446Slinton struct nl *nls_high; 142*5446Slinton }; 143*5446Slinton 144*5446Slinton struct nl nl[], *nlp, ntab[], *nlact; 145*5446Slinton 146*5446Slinton savenl(to, rout) 147*5446Slinton struct nl *to; 148*5446Slinton { 149*5446Slinton register struct nl *p; 150*5446Slinton register OBJSYM *s; 151*5446Slinton OBJSYM tmpsym; 152*5446Slinton struct nls *nlsp; 153*5446Slinton int v; 154*5446Slinton 155*5446Slinton if (to != NIL) { 156*5446Slinton putblock(rout); 157*5446Slinton } else { 158*5446Slinton putblock("main program"); 159*5446Slinton } 160*5446Slinton nlsp = nlact; 161*5446Slinton s = &tmpsym; 162*5446Slinton for (p = nlp; p != to;) { 163*5446Slinton if (p == nlsp->nls_low) { 164*5446Slinton if (nlsp == &ntab[0]) 165*5446Slinton break; 166*5446Slinton nlsp--; 167*5446Slinton p = nlsp->nls_high; 168*5446Slinton } 169*5446Slinton p--; 170*5446Slinton if (isbuiltin(p) || symno(p) == 0) { 171*5446Slinton continue; 172*5446Slinton } 173*5446Slinton nlhdr.nsyms++; 174*5446Slinton putw(symno(p), symfp); 175*5446Slinton if (p->symbol != NULL) { 176*5446Slinton s->strindex = nlhdr.stringsize; 177*5446Slinton putstring(p->symbol); 178*5446Slinton } else { 179*5446Slinton s->strindex = 0; 180*5446Slinton } 181*5446Slinton s->oclass = p->class; 182*5446Slinton s->oblkno = (p->nl_block&037); 183*5446Slinton s->typno = symno(p->type); 184*5446Slinton s->chno = symno(p->chain); 185*5446Slinton s->osymvalue.orangev.lower = p->range[0]; 186*5446Slinton s->osymvalue.orangev.upper = p->range[1]; 187*5446Slinton if (isblock(p)) { 188*5446Slinton s->osymvalue.ofuncv.codeloc = p->entloc; 189*5446Slinton } else if (p->class == RECORD || p->class == VARNT) { 190*5446Slinton s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]); 191*5446Slinton s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]); 192*5446Slinton } 193*5446Slinton fwrite(s, sizeof(*s), 1, symfp); 194*5446Slinton } 195*5446Slinton } 196*5446Slinton 197*5446Slinton /* 198*5446Slinton * Dump a line number and the current object location counter. 199*5446Slinton * 200*5446Slinton * To save space the difference from the previous line number and offset 201*5446Slinton * (one byte each) is dumped. 202*5446Slinton */ 203*5446Slinton 204*5446Slinton LOCAL int oline = 0; 205*5446Slinton LOCAL int olc = BASEADDR; 206*5446Slinton 207*5446Slinton lineno(line) 208*5446Slinton int line; 209*5446Slinton { 210*5446Slinton if (line != oline) { 211*5446Slinton nlhdr.nlines++; 212*5446Slinton putc(line - oline, linesfp); 213*5446Slinton putc(lc - olc, linesfp); 214*5446Slinton oline = line; 215*5446Slinton olc = lc; 216*5446Slinton } 217*5446Slinton } 218*5446Slinton 219*5446Slinton /* 220*5446Slinton * put out a file name entry, including: 221*5446Slinton * 222*5446Slinton * the current line number for the new file 223*5446Slinton * the current location counter 224*5446Slinton * the string table address of the file name 225*5446Slinton * an index into the current line number information 226*5446Slinton */ 227*5446Slinton 228*5446Slinton newfile(s, line) 229*5446Slinton char *s; 230*5446Slinton int line; 231*5446Slinton { 232*5446Slinton FILETAB ft; 233*5446Slinton 234*5446Slinton nlhdr.nfiles++; 235*5446Slinton ft.line = line; 236*5446Slinton oline = line; 237*5446Slinton if (lc == 0) { 238*5446Slinton ft.addr = 0; 239*5446Slinton } else { 240*5446Slinton ft.addr = lc - BASEADDR; 241*5446Slinton } 242*5446Slinton ft.filename = (char *) nlhdr.stringsize; 243*5446Slinton putstring(s); 244*5446Slinton ft.lineindex = nlhdr.nlines; 245*5446Slinton fwrite(&ft, sizeof(ft), 1, filesfp); 246*5446Slinton } 247*5446Slinton 248*5446Slinton /* 249*5446Slinton * put out a dummy symbol at the beginning of a block 250*5446Slinton */ 251*5446Slinton 252*5446Slinton LOCAL putblock(s) 253*5446Slinton char *s; 254*5446Slinton { 255*5446Slinton register int i; 256*5446Slinton static OBJSYM zerosym; 257*5446Slinton 258*5446Slinton nlhdr.nsyms++; 259*5446Slinton putw(0, symfp); 260*5446Slinton zerosym.strindex = nlhdr.stringsize; 261*5446Slinton putstring(s); 262*5446Slinton fwrite(&zerosym, sizeof(zerosym), 1, symfp); 263*5446Slinton } 264*5446Slinton 265*5446Slinton /* 266*5446Slinton * put out a string to the string table file 267*5446Slinton */ 268*5446Slinton 269*5446Slinton LOCAL putstring(s) 270*5446Slinton char *s; 271*5446Slinton { 272*5446Slinton register char *p; 273*5446Slinton 274*5446Slinton for (p = s; *p != '\0'; p++) 275*5446Slinton putc(*p, strfp); 276*5446Slinton nlhdr.stringsize += (p - s + 1); 277*5446Slinton putc('\0', strfp); 278*5446Slinton } 279