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