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: char copyright[] = 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: #endif not lint 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)int.c 5.1 (Berkeley) 6/5/85"; 15: #endif not lint 16: 17: /* 18: * px - interpreter for Berkeley Pascal 19: * Version 3.0 Winter 1979 20: * 21: * Original version for the PDP 11/70 authored by: 22: * Bill Joy, Charles Haley, Ken Thompson 23: * 24: * Rewritten for VAX 11/780 by Kirk McKusick 25: */ 26: 27: #include <signal.h> 28: #include "whoami.h" 29: #include "vars.h" 30: #include "libpc.h" 31: #include "objfmt.h" 32: 33: /* 34: * New stuff for pdx 35: */ 36: 37: extern char *end; 38: extern loopaddr(); 39: union progcntr *pcaddrp; /* address of interpreter frame address */ 40: 41: main(ac,av) 42: 43: int ac; 44: char **av; 45: 46: { 47: register char *objprog, *file; 48: char *name; 49: register long bytesread, bytestoread, block; 50: register FILE *prog; 51: struct pxhdr pxhd; 52: # define pipe 3 53: 54: /* 55: * Initialize everything 56: */ 57: _argc = ac; 58: _argv = av; 59: _nodump = FALSE; 60: 61: /* 62: * Determine how PX was invoked, and how to process the program 63: */ 64: file = _argv[1]; 65: if (!strcmp(_argv[0], "pdx")) { 66: _mode = PDX; 67: _argv += 2; _argc -= 2; 68: name = _argv[0]; 69: } else if (!strcmp(_argv[0], "pix")) { 70: _mode = PIX; 71: _argv++; _argc--; 72: name = _argv[0]; 73: } else if (!strcmp(_argv[0], "pipe")) { 74: _mode = PIPE; 75: file = "PIPE"; 76: _argv++; _argc--; 77: name = _argv[0]; 78: } else { 79: _mode = PX; 80: if (_argc <= 1) 81: file = "obj"; 82: name = file; 83: } 84: 85: /* 86: * kludge to check for old style objs. 87: */ 88: if (_mode == PX && !strcmp(file, "-")) { 89: fprintf(stderr, "%s is obsolete and must be recompiled\n", 90: _argv[0]); 91: exit(1); 92: } 93: /* 94: * Process program header information 95: */ 96: if (_mode == PIPE) { 97: read(pipe,&pxhd,sizeof(struct pxhdr)); 98: } else { 99: prog = fopen(file,"r"); 100: if (prog == NULL) { 101: perror(file); 102: exit(1); 103: } 104: fread(&pxhd,sizeof(struct pxhdr),1,prog); 105: if (pxhd.magicnum != MAGICNUM) { 106: fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0); 107: fread(&pxhd,sizeof(struct pxhdr),1,prog); 108: } 109: } 110: if (pxhd.magicnum != MAGICNUM) { 111: fprintf(stderr,"%s is not a Pascal interpreter file\n",name); 112: exit(1); 113: } 114: if (pxhd.maketime < createtime) { 115: fprintf(stderr,"%s is obsolete and must be recompiled\n",name); 116: exit(1); 117: } 118: 119: /* 120: * Load program into memory 121: */ 122: objprog = malloc((int)pxhd.objsize); 123: if (_mode == PIPE) { 124: bytestoread = pxhd.objsize; 125: bytesread = 0; 126: do { 127: block = read(pipe,(int)(objprog+bytesread),bytestoread); 128: if (block > 0) { 129: bytesread += block; 130: bytestoread -= block; 131: } 132: } while (block > 0); 133: } else { 134: bytesread = fread(objprog,1,(int)pxhd.objsize,prog); 135: fclose(prog); 136: } 137: if (bytesread != pxhd.objsize) { 138: fprintf(stderr,"Read error occurred while loading %s\n",file); 139: exit(1); 140: } 141: if (_mode == PIX) 142: fputs("Execution begins...\n",stderr); 143: /* 144: * set interpreter to catch expected signals and begin interpretation 145: */ 146: signal(SIGILL,syserr); 147: signal(SIGBUS,syserr); 148: signal(SIGSYS,syserr); 149: if (signal(SIGINT,SIG_IGN) != SIG_IGN) 150: signal(SIGINT,intr); 151: signal(SIGSEGV,memsize); 152: signal(SIGFPE,EXCEPT); 153: signal(SIGTRAP,liberr); 154: 155: /* 156: * See if we're being watched by the debugger, if so set a trap. 157: */ 158: if (_mode == PDX || (_mode == PIX && pxhd.symtabsize > 0)) { 159: inittrap(&_display, &_dp, objprog, &pcaddrp, loopaddr); 160: } 161: 162: /* 163: * do it 164: */ 165: interpreter(objprog); 166: /* 167: * reset signals, deallocate memory, and exit normally 168: */ 169: signal(SIGINT,SIG_IGN); 170: signal(SIGSEGV,SIG_DFL); 171: signal(SIGFPE,SIG_DFL); 172: signal(SIGTRAP,SIG_DFL); 173: signal(SIGILL,SIG_DFL); 174: signal(SIGBUS,SIG_DFL); 175: signal(SIGSYS,SIG_DFL); 176: PFLUSH(); 177: psexit(0); 178: } 179: 180: /* 181: * Generate an IOT trap to tell the debugger that the object code 182: * has been read in. Parameters are there for debugger to look at, 183: * not the procedure. 184: */ 185: 186: static inittrap(dispaddr, dpaddr, endaddr, pcaddrp, loopaddrp) 187: union disply *dispaddr; 188: struct disp *dpaddr; 189: char *endaddr; 190: union progcntr **pcaddrp; 191: char **loopaddrp; 192: { 193: kill(getpid(), SIGIOT); 194: }