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