12079Smckusick /* Copyright (c) 1979 Regents of the University of California */ 22079Smckusick 3*5744Smckusic static char sccsid[] = "@(#)int.c 1.8 02/11/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" 185678Smckusic #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 /* 74*5744Smckusic * kludge to check for old style objs. 75*5744Smckusic */ 76*5744Smckusic if (_mode == PX && !strcmp(file, "-")) { 77*5744Smckusic fprintf(stderr, "%s is obsolete and must be recompiled\n", 78*5744Smckusic _argv[0]); 79*5744Smckusic exit(1); 80*5744Smckusic } 81*5744Smckusic /* 822950Smckusic * Process program header information 832950Smckusic */ 843910Smckusic if (_mode == PIPE) { 852950Smckusic read(pipe,&pxhd,sizeof(struct pxhdr)); 863910Smckusic } else { 872950Smckusic prog = fopen(file,"r"); 883910Smckusic if (prog == NULL) { 892950Smckusic perror(file); 902950Smckusic exit(1); 913910Smckusic } 922950Smckusic fread(&pxhd,sizeof(struct pxhdr),1,prog); 935658Slinton if (pxhd.magicnum != MAGICNUM) { 945658Slinton fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0); 955658Slinton fread(&pxhd,sizeof(struct pxhdr),1,prog); 965658Slinton } 973910Smckusic } 985658Slinton if (pxhd.magicnum != MAGICNUM) { 995661Smckusic fprintf(stderr,"%s is not a Pascal interpreter file\n",name); 1005658Slinton exit(1); 1015658Slinton } 1023910Smckusic if (pxhd.maketime < createtime) { 1035661Smckusic fprintf(stderr,"%s is obsolete and must be recompiled\n",name); 1042079Smckusick exit(1); 1053910Smckusic } 1062079Smckusick 1072950Smckusic /* 1082950Smckusic * Load program into memory 1092950Smckusic */ 1102950Smckusic objprog = malloc((int)pxhd.objsize); 1113910Smckusic if (_mode == PIPE) { 1123910Smckusic bytestoread = pxhd.objsize; 1132950Smckusic bytesread = 0; 1143910Smckusic do { 1153910Smckusic block = read(pipe,(int)(objprog+bytesread),bytestoread); 1163910Smckusic if (block > 0) { 1173910Smckusic bytesread += block; 1183910Smckusic bytestoread -= block; 1192950Smckusic } 1203910Smckusic } while (block > 0); 1213910Smckusic } else { 1222950Smckusic bytesread = fread(objprog,1,(int)pxhd.objsize,prog); 1232950Smckusic fclose(prog); 1243910Smckusic } 1253910Smckusic if (bytesread != pxhd.objsize) { 1262950Smckusic fprintf(stderr,"Read error occurred while loading %s\n",file); 1272950Smckusic exit(1); 1283910Smckusic } 1292079Smckusick if (_mode == PIX) 1302950Smckusic fputs("Execution begins...\n",stderr); 1312950Smckusic /* 1322950Smckusic * set interpreter to catch expected signals and begin interpretation 1332950Smckusic */ 1342950Smckusic signal(SIGILL,syserr); 1352950Smckusic signal(SIGBUS,syserr); 1362950Smckusic signal(SIGSYS,syserr); 1372950Smckusic if (signal(SIGINT,SIG_IGN) != SIG_IGN) 1382950Smckusic signal(SIGINT,intr); 1392950Smckusic signal(SIGSEGV,memsize); 1405678Smckusic signal(SIGFPE,EXCEPT); 1412950Smckusic signal(SIGTRAP,liberr); 1425658Slinton 1432950Smckusic /* 1445658Slinton * See if we're being watched by the debugger, if so set a trap. 1455658Slinton */ 1465658Slinton if (_mode == PDX || (_mode == PIX && pxhd.symtabsize > 0)) { 1475658Slinton inittrap(&_display, &_dp, objprog, &pcaddrp, loopaddr); 1485658Slinton } 1495658Slinton 1505658Slinton /* 1512950Smckusic * do it 1522950Smckusic */ 1532950Smckusic interpreter(objprog); 1542950Smckusic /* 1552950Smckusic * reset signals, deallocate memory, and exit normally 1562950Smckusic */ 1572950Smckusic signal(SIGINT,SIG_IGN); 1582950Smckusic signal(SIGSEGV,SIG_DFL); 1592950Smckusic signal(SIGFPE,SIG_DFL); 1602950Smckusic signal(SIGTRAP,SIG_DFL); 1612950Smckusic signal(SIGILL,SIG_DFL); 1622950Smckusic signal(SIGBUS,SIG_DFL); 1632950Smckusic signal(SIGSYS,SIG_DFL); 1642950Smckusic PFLUSH(); 1652950Smckusic psexit(0); 1662079Smckusick } 1675658Slinton 1685658Slinton /* 1695658Slinton * Generate an IOT trap to tell the debugger that the object code 1705658Slinton * has been read in. Parameters are there for debugger to look at, 1715658Slinton * not the procedure. 1725658Slinton */ 1735658Slinton 1745658Slinton static inittrap(dispaddr, dpaddr, endaddr, pcaddrp, loopaddrp) 1755658Slinton union disply *dispaddr; 1765658Slinton struct disp *dpaddr; 1775658Slinton char *endaddr; 1785658Slinton union progcntr **pcaddrp; 1795658Slinton char **loopaddrp; 1805658Slinton { 1815658Slinton kill(getpid(), SIGIOT); 1825658Slinton } 183