12079Smckusick /* Copyright (c) 1979 Regents of the University of California */ 22079Smckusick 3*5661Smckusic static char sccsid[] = "@(#)int.c 1.6 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 205658Slinton /* 215658Slinton * New stuff for pdx 225658Slinton */ 235658Slinton 245658Slinton extern char *end; 255658Slinton extern loopaddr(); 265658Slinton union progcntr *pcaddrp; /* address of interpreter frame address */ 275658Slinton 282079Smckusick main(ac,av) 292079Smckusick 302950Smckusic int ac; 312950Smckusic char **av; 322079Smckusick 332079Smckusick { 342950Smckusic register char *objprog, *file; 35*5661Smckusic char *name; 363910Smckusic register long bytesread, bytestoread, block; 372950Smckusic register FILE *prog; 382950Smckusic struct pxhdr pxhd; 392950Smckusic # define pipe 3 402079Smckusick 412950Smckusic /* 422950Smckusic * Initialize everything 432950Smckusic */ 442950Smckusic _argc = ac; 452950Smckusic _argv = av; 462950Smckusic _nodump = FALSE; 472079Smckusick 482950Smckusic /* 492950Smckusic * Determine how PX was invoked, and how to process the program 502950Smckusic */ 515658Slinton file = _argv[1]; 525658Slinton if (!strcmp(_argv[0], "pdx")) { 535658Slinton _mode = PDX; 545658Slinton _argv += 2; _argc -= 2; 55*5661Smckusic name = _argv[0]; 565658Slinton } else if (!strcmp(_argv[0], "pix")) { 572950Smckusic _mode = PIX; 585658Slinton _argv++; _argc--; 59*5661Smckusic name = _argv[0]; 605658Slinton } else if (!strcmp(_argv[0], "pipe")) { 612950Smckusic _mode = PIPE; 625658Slinton file = "PIPE"; 635658Slinton _argv++; _argc--; 64*5661Smckusic name = _argv[0]; 653910Smckusic } else { 665658Slinton _mode = PX; 675658Slinton if (_argc <= 1) 685658Slinton file = "obj"; 69*5661Smckusic name = file; 703910Smckusic } 712079Smckusick 722950Smckusic /* 732950Smckusic * Process program header information 742950Smckusic */ 753910Smckusic if (_mode == PIPE) { 762950Smckusic read(pipe,&pxhd,sizeof(struct pxhdr)); 773910Smckusic } else { 782950Smckusic prog = fopen(file,"r"); 793910Smckusic if (prog == NULL) { 802950Smckusic perror(file); 812950Smckusic exit(1); 823910Smckusic } 832950Smckusic fread(&pxhd,sizeof(struct pxhdr),1,prog); 845658Slinton if (pxhd.magicnum != MAGICNUM) { 855658Slinton fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0); 865658Slinton fread(&pxhd,sizeof(struct pxhdr),1,prog); 875658Slinton } 883910Smckusic } 895658Slinton if (pxhd.magicnum != MAGICNUM) { 90*5661Smckusic fprintf(stderr,"%s is not a Pascal interpreter file\n",name); 915658Slinton exit(1); 925658Slinton } 933910Smckusic if (pxhd.maketime < createtime) { 94*5661Smckusic fprintf(stderr,"%s is obsolete and must be recompiled\n",name); 952079Smckusick exit(1); 963910Smckusic } 972079Smckusick 982950Smckusic /* 992950Smckusic * Load program into memory 1002950Smckusic */ 1012950Smckusic objprog = malloc((int)pxhd.objsize); 1023910Smckusic if (_mode == PIPE) { 1033910Smckusic bytestoread = pxhd.objsize; 1042950Smckusic bytesread = 0; 1053910Smckusic do { 1063910Smckusic block = read(pipe,(int)(objprog+bytesread),bytestoread); 1073910Smckusic if (block > 0) { 1083910Smckusic bytesread += block; 1093910Smckusic bytestoread -= block; 1102950Smckusic } 1113910Smckusic } while (block > 0); 1123910Smckusic } else { 1132950Smckusic bytesread = fread(objprog,1,(int)pxhd.objsize,prog); 1142950Smckusic fclose(prog); 1153910Smckusic } 1163910Smckusic if (bytesread != pxhd.objsize) { 1172950Smckusic fprintf(stderr,"Read error occurred while loading %s\n",file); 1182950Smckusic exit(1); 1193910Smckusic } 1202079Smckusick if (_mode == PIX) 1212950Smckusic fputs("Execution begins...\n",stderr); 1222950Smckusic /* 1232950Smckusic * set interpreter to catch expected signals and begin interpretation 1242950Smckusic */ 1252950Smckusic signal(SIGILL,syserr); 1262950Smckusic signal(SIGBUS,syserr); 1272950Smckusic signal(SIGSYS,syserr); 1282950Smckusic if (signal(SIGINT,SIG_IGN) != SIG_IGN) 1292950Smckusic signal(SIGINT,intr); 1302950Smckusic signal(SIGSEGV,memsize); 1312950Smckusic signal(SIGFPE,except); 1322950Smckusic signal(SIGTRAP,liberr); 1335658Slinton 1342950Smckusic /* 1355658Slinton * See if we're being watched by the debugger, if so set a trap. 1365658Slinton */ 1375658Slinton if (_mode == PDX || (_mode == PIX && pxhd.symtabsize > 0)) { 1385658Slinton inittrap(&_display, &_dp, objprog, &pcaddrp, loopaddr); 1395658Slinton } 1405658Slinton 1415658Slinton /* 1422950Smckusic * do it 1432950Smckusic */ 1442950Smckusic interpreter(objprog); 1452950Smckusic /* 1462950Smckusic * reset signals, deallocate memory, and exit normally 1472950Smckusic */ 1482950Smckusic signal(SIGINT,SIG_IGN); 1492950Smckusic signal(SIGSEGV,SIG_DFL); 1502950Smckusic signal(SIGFPE,SIG_DFL); 1512950Smckusic signal(SIGTRAP,SIG_DFL); 1522950Smckusic signal(SIGILL,SIG_DFL); 1532950Smckusic signal(SIGBUS,SIG_DFL); 1542950Smckusic signal(SIGSYS,SIG_DFL); 1552950Smckusic PFLUSH(); 1562950Smckusic /* pfree(objprog); */ 1572950Smckusic psexit(0); 1582079Smckusick } 1595658Slinton 1605658Slinton /* 1615658Slinton * Generate an IOT trap to tell the debugger that the object code 1625658Slinton * has been read in. Parameters are there for debugger to look at, 1635658Slinton * not the procedure. 1645658Slinton */ 1655658Slinton 1665658Slinton static inittrap(dispaddr, dpaddr, endaddr, pcaddrp, loopaddrp) 1675658Slinton union disply *dispaddr; 1685658Slinton struct disp *dpaddr; 1695658Slinton char *endaddr; 1705658Slinton union progcntr **pcaddrp; 1715658Slinton char **loopaddrp; 1725658Slinton { 1735658Slinton kill(getpid(), SIGIOT); 1745658Slinton } 175