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