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