1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)savenl.c 1.3 02/11/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 OBJLINE info; 232 233 if (line != oline) { 234 nlhdr.nlines++; 235 nlsize += sizeof(OBJLINE); 236 info.separate.lineincr = line - oline; 237 info.separate.addrincr = lc - olc; 238 putw(info.together, linesfp); 239 oline = line; 240 olc = lc; 241 } 242 } 243 244 /* 245 * put out a file name entry, including: 246 * 247 * the current line number for the new file 248 * the current location counter 249 * the string table address of the file name 250 * an index into the current line number information 251 */ 252 253 newfile(s, line) 254 char *s; 255 int line; 256 { 257 FILETAB ft; 258 259 nlhdr.nfiles++; 260 nlsize += sizeof(FILETAB); 261 ft.line = line; 262 oline = line; 263 if (lc == 0) { 264 ft.addr = 0; 265 } else { 266 ft.addr = lc - HEADER_BYTES; 267 } 268 ft.filename = (char *) nlhdr.stringsize; 269 putstring(s); 270 ft.lineindex = nlhdr.nlines; 271 fwrite(&ft, sizeof(ft), 1, filesfp); 272 } 273 274 /* 275 * put out a dummy symbol at the beginning of a block 276 */ 277 278 LOCAL putblock(s) 279 char *s; 280 { 281 register int i; 282 static OBJSYM zerosym; 283 284 nlhdr.nsyms++; 285 nlsize += sizeof(OBJSYM) + sizeof(int); 286 putw(0, symfp); 287 zerosym.strindex = nlhdr.stringsize; 288 putstring(s); 289 fwrite(&zerosym, sizeof(zerosym), 1, symfp); 290 } 291 292 /* 293 * put out a string to the string table file 294 */ 295 296 LOCAL putstring(s) 297 char *s; 298 { 299 register char *p; 300 301 for (p = s; *p != '\0'; p++) { 302 putc(*p, strfp); 303 } 304 nlhdr.stringsize += (p - s + 1); 305 nlsize += (p - s + 1); 306 putc('\0', strfp); 307 } 308