|
|
1.1 ! root 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.