12079Smckusick /* Copyright (c) 1979 Regents of the University of California */ 22079Smckusick 3*5678Smckusic static char sccsid[] = "@(#)int.c 1.7 02/03/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" 18*5678Smckusic #include "libpc.h" 192079Smckusick #include "objfmt.h" 202079Smckusick 215658Slinton /* 225658Slinton * New stuff for pdx 235658Slinton */ 245658Slinton 255658Slinton extern char *end; 265658Slinton extern loopaddr(); 275658Slinton union progcntr *pcaddrp; /* address of interpreter frame address */ 285658Slinton 292079Smckusick main(ac,av) 302079Smckusick 312950Smckusic int ac; 322950Smckusic char **av; 332079Smckusick 342079Smckusick { 352950Smckusic register char *objprog, *file; 365661Smckusic char *name; 373910Smckusic register long bytesread, bytestoread, block; 382950Smckusic register FILE *prog; 392950Smckusic struct pxhdr pxhd; 402950Smckusic # define pipe 3 412079Smckusick 422950Smckusic /* 432950Smckusic * Initialize everything 442950Smckusic */ 452950Smckusic _argc = ac; 462950Smckusic _argv = av; 472950Smckusic _nodump = FALSE; 482079Smckusick 492950Smckusic /* 502950Smckusic * Determine how PX was invoked, and how to process the program 512950Smckusic */ 525658Slinton file = _argv[1]; 535658Slinton if (!strcmp(_argv[0], "pdx")) { 545658Slinton _mode = PDX; 555658Slinton _argv += 2; _argc -= 2; 565661Smckusic name = _argv[0]; 575658Slinton } else if (!strcmp(_argv[0], "pix")) { 582950Smckusic _mode = PIX; 595658Slinton _argv++; _argc--; 605661Smckusic name = _argv[0]; 615658Slinton } else if (!strcmp(_argv[0], "pipe")) { 622950Smckusic _mode = PIPE; 635658Slinton file = "PIPE"; 645658Slinton _argv++; _argc--; 655661Smckusic name = _argv[0]; 663910Smckusic } else { 675658Slinton _mode = PX; 685658Slinton if (_argc <= 1) 695658Slinton file = "obj"; 705661Smckusic name = file; 713910Smckusic } 722079Smckusick 732950Smckusic /* 742950Smckusic * Process program header information 752950Smckusic */ 763910Smckusic if (_mode == PIPE) { 772950Smckusic read(pipe,&pxhd,sizeof(struct pxhdr)); 783910Smckusic } else { 792950Smckusic prog = fopen(file,"r"); 803910Smckusic if (prog == NULL) { 812950Smckusic perror(file); 822950Smckusic exit(1); 833910Smckusic } 842950Smckusic fread(&pxhd,sizeof(struct pxhdr),1,prog); 855658Slinton if (pxhd.magicnum != MAGICNUM) { 865658Slinton fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0); 875658Slinton fread(&pxhd,sizeof(struct pxhdr),1,prog); 885658Slinton } 893910Smckusic } 905658Slinton if (pxhd.magicnum != MAGICNUM) { 915661Smckusic fprintf(stderr,"%s is not a Pascal interpreter file\n",name); 925658Slinton exit(1); 935658Slinton } 943910Smckusic if (pxhd.maketime < createtime) { 955661Smckusic fprintf(stderr,"%s is obsolete and must be recompiled\n",name); 962079Smckusick exit(1); 973910Smckusic } 982079Smckusick 992950Smckusic /* 1002950Smckusic * Load program into memory 1012950Smckusic */ 1022950Smckusic objprog = malloc((int)pxhd.objsize); 1033910Smckusic if (_mode == PIPE) { 1043910Smckusic bytestoread = pxhd.objsize; 1052950Smckusic bytesread = 0; 1063910Smckusic do { 1073910Smckusic block = read(pipe,(int)(objprog+bytesread),bytestoread); 1083910Smckusic if (block > 0) { 1093910Smckusic bytesread += block; 1103910Smckusic bytestoread -= block; 1112950Smckusic } 1123910Smckusic } while (block > 0); 1133910Smckusic } else { 1142950Smckusic bytesread = fread(objprog,1,(int)pxhd.objsize,prog); 1152950Smckusic fclose(prog); 1163910Smckusic } 1173910Smckusic if (bytesread != pxhd.objsize) { 1182950Smckusic fprintf(stderr,"Read error occurred while loading %s\n",file); 1192950Smckusic exit(1); 1203910Smckusic } 1212079Smckusick if (_mode == PIX) 1222950Smckusic fputs("Execution begins...\n",stderr); 1232950Smckusic /* 1242950Smckusic * set interpreter to catch expected signals and begin interpretation 1252950Smckusic */ 1262950Smckusic signal(SIGILL,syserr); 1272950Smckusic signal(SIGBUS,syserr); 1282950Smckusic signal(SIGSYS,syserr); 1292950Smckusic if (signal(SIGINT,SIG_IGN) != SIG_IGN) 1302950Smckusic signal(SIGINT,intr); 1312950Smckusic signal(SIGSEGV,memsize); 132*5678Smckusic signal(SIGFPE,EXCEPT); 1332950Smckusic signal(SIGTRAP,liberr); 1345658Slinton 1352950Smckusic /* 1365658Slinton * See if we're being watched by the debugger, if so set a trap. 1375658Slinton */ 1385658Slinton if (_mode == PDX || (_mode == PIX && pxhd.symtabsize > 0)) { 1395658Slinton inittrap(&_display, &_dp, objprog, &pcaddrp, loopaddr); 1405658Slinton } 1415658Slinton 1425658Slinton /* 1432950Smckusic * do it 1442950Smckusic */ 1452950Smckusic interpreter(objprog); 1462950Smckusic /* 1472950Smckusic * reset signals, deallocate memory, and exit normally 1482950Smckusic */ 1492950Smckusic signal(SIGINT,SIG_IGN); 1502950Smckusic signal(SIGSEGV,SIG_DFL); 1512950Smckusic signal(SIGFPE,SIG_DFL); 1522950Smckusic signal(SIGTRAP,SIG_DFL); 1532950Smckusic signal(SIGILL,SIG_DFL); 1542950Smckusic signal(SIGBUS,SIG_DFL); 1552950Smckusic signal(SIGSYS,SIG_DFL); 1562950Smckusic PFLUSH(); 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