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