12079Smckusick /* Copyright (c) 1979 Regents of the University of California */ 22079Smckusick 3*5658Slinton static char sccsid[] = "@(#)int.c 1.5 02/02/82"; 42079Smckusick 52079Smckusick /* 62079Smckusick * px - interpreter for Berkeley Pascal 72079Smckusick * Version 3.0 Winter 1979 82079Smckusick * 92079Smckusick * Original version for the PDP 11/70 authored by: 102079Smckusick * Bill Joy, Charles Haley, Ken Thompson 112079Smckusick * 122079Smckusick * Rewritten for VAX 11/780 by Kirk McKusick 132079Smckusick */ 142079Smckusick 152079Smckusick #include <signal.h> 162950Smckusic #include "whoami.h" 172079Smckusick #include "vars.h" 182079Smckusick #include "objfmt.h" 192079Smckusick 20*5658Slinton /* 21*5658Slinton * New stuff for pdx 22*5658Slinton */ 23*5658Slinton 24*5658Slinton extern char *end; 25*5658Slinton extern loopaddr(); 26*5658Slinton union progcntr *pcaddrp; /* address of interpreter frame address */ 27*5658Slinton 282079Smckusick main(ac,av) 292079Smckusick 302950Smckusic int ac; 312950Smckusic char **av; 322079Smckusick 332079Smckusick { 342950Smckusic register char *objprog, *file; 353910Smckusic register long bytesread, bytestoread, block; 362950Smckusic register FILE *prog; 372950Smckusic struct pxhdr pxhd; 382950Smckusic # define pipe 3 392079Smckusick 402950Smckusic /* 412950Smckusic * Initialize everything 422950Smckusic */ 432950Smckusic _argc = ac; 442950Smckusic _argv = av; 452950Smckusic _nodump = FALSE; 462079Smckusick 472950Smckusic /* 482950Smckusic * Determine how PX was invoked, and how to process the program 492950Smckusic */ 50*5658Slinton file = _argv[1]; 51*5658Slinton if (!strcmp(_argv[0], "pdx")) { 52*5658Slinton _mode = PDX; 53*5658Slinton _argv += 2; _argc -= 2; 54*5658Slinton } else if (!strcmp(_argv[0], "pix")) { 552950Smckusic _mode = PIX; 56*5658Slinton _argv++; _argc--; 57*5658Slinton } else if (!strcmp(_argv[0], "pipe")) { 582950Smckusic _mode = PIPE; 59*5658Slinton file = "PIPE"; 60*5658Slinton _argv++; _argc--; 613910Smckusic } else { 62*5658Slinton _mode = PX; 63*5658Slinton if (_argc <= 1) 64*5658Slinton file = "obj"; 653910Smckusic } 662079Smckusick 672950Smckusic /* 682950Smckusic * Process program header information 692950Smckusic */ 703910Smckusic if (_mode == PIPE) { 712950Smckusic read(pipe,&pxhd,sizeof(struct pxhdr)); 723910Smckusic } else { 732950Smckusic prog = fopen(file,"r"); 743910Smckusic if (prog == NULL) { 752950Smckusic perror(file); 762950Smckusic exit(1); 773910Smckusic } 782950Smckusic fread(&pxhd,sizeof(struct pxhdr),1,prog); 79*5658Slinton if (pxhd.magicnum != MAGICNUM) { 80*5658Slinton fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0); 81*5658Slinton fread(&pxhd,sizeof(struct pxhdr),1,prog); 82*5658Slinton } 833910Smckusic } 84*5658Slinton if (pxhd.magicnum != MAGICNUM) { 85*5658Slinton fprintf(stderr,"%s is not a Pascal interpreter file\n",file); 86*5658Slinton exit(1); 87*5658Slinton } 883910Smckusic if (pxhd.maketime < createtime) { 892950Smckusic fprintf(stderr,"%s is obsolete and must be recompiled\n",file); 902079Smckusick exit(1); 913910Smckusic } 922079Smckusick 932950Smckusic /* 942950Smckusic * Load program into memory 952950Smckusic */ 962950Smckusic objprog = malloc((int)pxhd.objsize); 973910Smckusic if (_mode == PIPE) { 983910Smckusic bytestoread = pxhd.objsize; 992950Smckusic bytesread = 0; 1003910Smckusic do { 1013910Smckusic block = read(pipe,(int)(objprog+bytesread),bytestoread); 1023910Smckusic if (block > 0) { 1033910Smckusic bytesread += block; 1043910Smckusic bytestoread -= block; 1052950Smckusic } 1063910Smckusic } while (block > 0); 1073910Smckusic } else { 1082950Smckusic bytesread = fread(objprog,1,(int)pxhd.objsize,prog); 1092950Smckusic fclose(prog); 1103910Smckusic } 1113910Smckusic if (bytesread != pxhd.objsize) { 1122950Smckusic fprintf(stderr,"Read error occurred while loading %s\n",file); 1132950Smckusic exit(1); 1143910Smckusic } 1152079Smckusick if (_mode == PIX) 1162950Smckusic fputs("Execution begins...\n",stderr); 1172950Smckusic /* 1182950Smckusic * set interpreter to catch expected signals and begin interpretation 1192950Smckusic */ 1202950Smckusic signal(SIGILL,syserr); 1212950Smckusic signal(SIGBUS,syserr); 1222950Smckusic signal(SIGSYS,syserr); 1232950Smckusic if (signal(SIGINT,SIG_IGN) != SIG_IGN) 1242950Smckusic signal(SIGINT,intr); 1252950Smckusic signal(SIGSEGV,memsize); 1262950Smckusic signal(SIGFPE,except); 1272950Smckusic signal(SIGTRAP,liberr); 128*5658Slinton 1292950Smckusic /* 130*5658Slinton * See if we're being watched by the debugger, if so set a trap. 131*5658Slinton */ 132*5658Slinton if (_mode == PDX || (_mode == PIX && pxhd.symtabsize > 0)) { 133*5658Slinton inittrap(&_display, &_dp, objprog, &pcaddrp, loopaddr); 134*5658Slinton } 135*5658Slinton 136*5658Slinton /* 1372950Smckusic * do it 1382950Smckusic */ 1392950Smckusic interpreter(objprog); 1402950Smckusic /* 1412950Smckusic * reset signals, deallocate memory, and exit normally 1422950Smckusic */ 1432950Smckusic signal(SIGINT,SIG_IGN); 1442950Smckusic signal(SIGSEGV,SIG_DFL); 1452950Smckusic signal(SIGFPE,SIG_DFL); 1462950Smckusic signal(SIGTRAP,SIG_DFL); 1472950Smckusic signal(SIGILL,SIG_DFL); 1482950Smckusic signal(SIGBUS,SIG_DFL); 1492950Smckusic signal(SIGSYS,SIG_DFL); 1502950Smckusic PFLUSH(); 1512950Smckusic /* pfree(objprog); */ 1522950Smckusic psexit(0); 1532079Smckusick } 154*5658Slinton 155*5658Slinton /* 156*5658Slinton * Generate an IOT trap to tell the debugger that the object code 157*5658Slinton * has been read in. Parameters are there for debugger to look at, 158*5658Slinton * not the procedure. 159*5658Slinton */ 160*5658Slinton 161*5658Slinton static inittrap(dispaddr, dpaddr, endaddr, pcaddrp, loopaddrp) 162*5658Slinton union disply *dispaddr; 163*5658Slinton struct disp *dpaddr; 164*5658Slinton char *endaddr; 165*5658Slinton union progcntr **pcaddrp; 166*5658Slinton char **loopaddrp; 167*5658Slinton { 168*5658Slinton kill(getpid(), SIGIOT); 169*5658Slinton } 170