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