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) 06/05/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 } 195