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.2 (Berkeley) 01/09/89"; 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 extern union progcntr pdx_pc; /* address of interpreter program cntr */ 40 static void inittrap(); 41 42 main(ac,av) 43 44 int ac; 45 char **av; 46 47 { 48 register char *objprog, *file; 49 char *name; 50 register long bytesread, bytestoread, block; 51 register FILE *prog; 52 struct pxhdr pxhd; 53 # define pipe 3 54 55 /* 56 * Initialize everything 57 */ 58 _argc = ac; 59 _argv = av; 60 _nodump = FALSE; 61 62 /* 63 * Determine how PX was invoked, and how to process the program 64 */ 65 file = _argv[1]; 66 if (!strcmp(_argv[0], "pdx")) { 67 _mode = PDX; 68 _argv += 2; _argc -= 2; 69 name = _argv[0]; 70 } else if (!strcmp(_argv[0], "pix")) { 71 _mode = PIX; 72 _argv++; _argc--; 73 name = _argv[0]; 74 } else if (!strcmp(_argv[0], "pipe")) { 75 _mode = PIPE; 76 file = "PIPE"; 77 _argv++; _argc--; 78 name = _argv[0]; 79 } else { 80 _mode = PX; 81 if (_argc <= 1) 82 file = "obj"; 83 name = file; 84 } 85 86 /* 87 * kludge to check for old style objs. 88 */ 89 if (_mode == PX && !strcmp(file, "-")) { 90 fprintf(stderr, "%s is obsolete and must be recompiled\n", 91 _argv[0]); 92 exit(1); 93 } 94 /* 95 * Process program header information 96 */ 97 if (_mode == PIPE) { 98 read(pipe,&pxhd,sizeof(struct pxhdr)); 99 } else { 100 prog = fopen(file,"r"); 101 if (prog == NULL) { 102 perror(file); 103 exit(1); 104 } 105 fread(&pxhd,sizeof(struct pxhdr),1,prog); 106 if (pxhd.magicnum != MAGICNUM) { 107 fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0); 108 fread(&pxhd,sizeof(struct pxhdr),1,prog); 109 } 110 } 111 if (pxhd.magicnum != MAGICNUM) { 112 fprintf(stderr,"%s is not a Pascal interpreter file\n",name); 113 exit(1); 114 } 115 if (pxhd.maketime < createtime) { 116 fprintf(stderr,"%s is obsolete and must be recompiled\n",name); 117 exit(1); 118 } 119 120 /* 121 * Load program into memory 122 */ 123 objprog = malloc((int)pxhd.objsize); 124 if (_mode == PIPE) { 125 bytestoread = pxhd.objsize; 126 bytesread = 0; 127 do { 128 block = read(pipe,(int)(objprog+bytesread),bytestoread); 129 if (block > 0) { 130 bytesread += block; 131 bytestoread -= block; 132 } 133 } while (block > 0); 134 } else { 135 bytesread = fread(objprog,1,(int)pxhd.objsize,prog); 136 fclose(prog); 137 } 138 if (bytesread != pxhd.objsize) { 139 fprintf(stderr,"Read error occurred while loading %s\n",file); 140 exit(1); 141 } 142 if (_mode == PIX) 143 fputs("Execution begins...\n",stderr); 144 /* 145 * set interpreter to catch expected signals and begin interpretation 146 */ 147 signal(SIGILL,syserr); 148 signal(SIGBUS,syserr); 149 signal(SIGSYS,syserr); 150 if (signal(SIGINT,SIG_IGN) != SIG_IGN) 151 signal(SIGINT,intr); 152 signal(SIGSEGV,memsize); 153 signal(SIGFPE,EXCEPT); 154 signal(SIGTRAP,liberr); 155 156 /* 157 * See if we're being watched by the debugger, if so set a trap. 158 */ 159 if (_mode == PDX || (_mode == PIX && pxhd.symtabsize > 0)) { 160 inittrap(&_display, &_dp, objprog, &pdx_pc, loopaddr); 161 } 162 163 /* 164 * do it 165 */ 166 interpreter(objprog); 167 /* 168 * reset signals, deallocate memory, and exit normally 169 */ 170 signal(SIGINT,SIG_IGN); 171 signal(SIGSEGV,SIG_DFL); 172 signal(SIGFPE,SIG_DFL); 173 signal(SIGTRAP,SIG_DFL); 174 signal(SIGILL,SIG_DFL); 175 signal(SIGBUS,SIG_DFL); 176 signal(SIGSYS,SIG_DFL); 177 PFLUSH(); 178 psexit(0); 179 } 180 181 /* 182 * Generate an IOT trap to tell the debugger that the object code 183 * has been read in. Parameters are there for debugger to look at, 184 * not the procedure. 185 */ 186 187 static void 188 inittrap(dispaddr, dpaddr, endaddr, pcaddr, loopaddrp) 189 union disply *dispaddr; 190 struct disp *dpaddr; 191 char *endaddr; 192 union progcntr *pcaddr; 193 char **loopaddrp; 194 { 195 kill(getpid(), SIGIOT); 196 } 197