122151Sdist /* 222151Sdist * Copyright (c) 1980 Regents of the University of California. 322151Sdist * All rights reserved. The Berkeley software License Agreement 422151Sdist * specifies the terms and conditions for redistribution. 522151Sdist */ 62079Smckusick 722151Sdist #ifndef lint 822151Sdist char copyright[] = 922151Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1022151Sdist All rights reserved.\n"; 1122151Sdist #endif not lint 122079Smckusick 1322151Sdist #ifndef lint 14*36537Smckusick static char sccsid[] = "@(#)int.c 5.2 (Berkeley) 01/09/89"; 1522151Sdist #endif not lint 1622151Sdist 172079Smckusick /* 182079Smckusick * px - interpreter for Berkeley Pascal 192079Smckusick * Version 3.0 Winter 1979 202079Smckusick * 212079Smckusick * Original version for the PDP 11/70 authored by: 222079Smckusick * Bill Joy, Charles Haley, Ken Thompson 232079Smckusick * 242079Smckusick * Rewritten for VAX 11/780 by Kirk McKusick 252079Smckusick */ 262079Smckusick 272079Smckusick #include <signal.h> 282950Smckusic #include "whoami.h" 292079Smckusick #include "vars.h" 305678Smckusic #include "libpc.h" 312079Smckusick #include "objfmt.h" 322079Smckusick 335658Slinton /* 345658Slinton * New stuff for pdx 355658Slinton */ 365658Slinton 375658Slinton extern char *end; 385658Slinton extern loopaddr(); 39*36537Smckusick extern union progcntr pdx_pc; /* address of interpreter program cntr */ 40*36537Smckusick static void inittrap(); 415658Slinton 422079Smckusick main(ac,av) 432079Smckusick 442950Smckusic int ac; 452950Smckusic char **av; 462079Smckusick 472079Smckusick { 482950Smckusic register char *objprog, *file; 495661Smckusic char *name; 503910Smckusic register long bytesread, bytestoread, block; 512950Smckusic register FILE *prog; 522950Smckusic struct pxhdr pxhd; 532950Smckusic # define pipe 3 542079Smckusick 552950Smckusic /* 562950Smckusic * Initialize everything 572950Smckusic */ 582950Smckusic _argc = ac; 592950Smckusic _argv = av; 602950Smckusic _nodump = FALSE; 612079Smckusick 622950Smckusic /* 632950Smckusic * Determine how PX was invoked, and how to process the program 642950Smckusic */ 655658Slinton file = _argv[1]; 665658Slinton if (!strcmp(_argv[0], "pdx")) { 675658Slinton _mode = PDX; 685658Slinton _argv += 2; _argc -= 2; 695661Smckusic name = _argv[0]; 705658Slinton } else if (!strcmp(_argv[0], "pix")) { 712950Smckusic _mode = PIX; 725658Slinton _argv++; _argc--; 735661Smckusic name = _argv[0]; 745658Slinton } else if (!strcmp(_argv[0], "pipe")) { 752950Smckusic _mode = PIPE; 765658Slinton file = "PIPE"; 775658Slinton _argv++; _argc--; 785661Smckusic name = _argv[0]; 793910Smckusic } else { 805658Slinton _mode = PX; 815658Slinton if (_argc <= 1) 825658Slinton file = "obj"; 835661Smckusic name = file; 843910Smckusic } 852079Smckusick 862950Smckusic /* 875744Smckusic * kludge to check for old style objs. 885744Smckusic */ 895744Smckusic if (_mode == PX && !strcmp(file, "-")) { 905744Smckusic fprintf(stderr, "%s is obsolete and must be recompiled\n", 915744Smckusic _argv[0]); 925744Smckusic exit(1); 935744Smckusic } 945744Smckusic /* 952950Smckusic * Process program header information 962950Smckusic */ 973910Smckusic if (_mode == PIPE) { 982950Smckusic read(pipe,&pxhd,sizeof(struct pxhdr)); 993910Smckusic } else { 1002950Smckusic prog = fopen(file,"r"); 1013910Smckusic if (prog == NULL) { 1022950Smckusic perror(file); 1032950Smckusic exit(1); 1043910Smckusic } 1052950Smckusic fread(&pxhd,sizeof(struct pxhdr),1,prog); 1065658Slinton if (pxhd.magicnum != MAGICNUM) { 1075658Slinton fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0); 1085658Slinton fread(&pxhd,sizeof(struct pxhdr),1,prog); 1095658Slinton } 1103910Smckusic } 1115658Slinton if (pxhd.magicnum != MAGICNUM) { 1125661Smckusic fprintf(stderr,"%s is not a Pascal interpreter file\n",name); 1135658Slinton exit(1); 1145658Slinton } 1153910Smckusic if (pxhd.maketime < createtime) { 1165661Smckusic fprintf(stderr,"%s is obsolete and must be recompiled\n",name); 1172079Smckusick exit(1); 1183910Smckusic } 1192079Smckusick 1202950Smckusic /* 1212950Smckusic * Load program into memory 1222950Smckusic */ 1232950Smckusic objprog = malloc((int)pxhd.objsize); 1243910Smckusic if (_mode == PIPE) { 1253910Smckusic bytestoread = pxhd.objsize; 1262950Smckusic bytesread = 0; 1273910Smckusic do { 1283910Smckusic block = read(pipe,(int)(objprog+bytesread),bytestoread); 1293910Smckusic if (block > 0) { 1303910Smckusic bytesread += block; 1313910Smckusic bytestoread -= block; 1322950Smckusic } 1333910Smckusic } while (block > 0); 1343910Smckusic } else { 1352950Smckusic bytesread = fread(objprog,1,(int)pxhd.objsize,prog); 1362950Smckusic fclose(prog); 1373910Smckusic } 1383910Smckusic if (bytesread != pxhd.objsize) { 1392950Smckusic fprintf(stderr,"Read error occurred while loading %s\n",file); 1402950Smckusic exit(1); 1413910Smckusic } 1422079Smckusick if (_mode == PIX) 1432950Smckusic fputs("Execution begins...\n",stderr); 1442950Smckusic /* 1452950Smckusic * set interpreter to catch expected signals and begin interpretation 1462950Smckusic */ 1472950Smckusic signal(SIGILL,syserr); 1482950Smckusic signal(SIGBUS,syserr); 1492950Smckusic signal(SIGSYS,syserr); 1502950Smckusic if (signal(SIGINT,SIG_IGN) != SIG_IGN) 1512950Smckusic signal(SIGINT,intr); 1522950Smckusic signal(SIGSEGV,memsize); 1535678Smckusic signal(SIGFPE,EXCEPT); 1542950Smckusic signal(SIGTRAP,liberr); 1555658Slinton 1562950Smckusic /* 1575658Slinton * See if we're being watched by the debugger, if so set a trap. 1585658Slinton */ 1595658Slinton if (_mode == PDX || (_mode == PIX && pxhd.symtabsize > 0)) { 160*36537Smckusick inittrap(&_display, &_dp, objprog, &pdx_pc, loopaddr); 1615658Slinton } 1625658Slinton 1635658Slinton /* 1642950Smckusic * do it 1652950Smckusic */ 1662950Smckusic interpreter(objprog); 1672950Smckusic /* 1682950Smckusic * reset signals, deallocate memory, and exit normally 1692950Smckusic */ 1702950Smckusic signal(SIGINT,SIG_IGN); 1712950Smckusic signal(SIGSEGV,SIG_DFL); 1722950Smckusic signal(SIGFPE,SIG_DFL); 1732950Smckusic signal(SIGTRAP,SIG_DFL); 1742950Smckusic signal(SIGILL,SIG_DFL); 1752950Smckusic signal(SIGBUS,SIG_DFL); 1762950Smckusic signal(SIGSYS,SIG_DFL); 1772950Smckusic PFLUSH(); 1782950Smckusic psexit(0); 1792079Smckusick } 1805658Slinton 1815658Slinton /* 1825658Slinton * Generate an IOT trap to tell the debugger that the object code 1835658Slinton * has been read in. Parameters are there for debugger to look at, 1845658Slinton * not the procedure. 1855658Slinton */ 1865658Slinton 187*36537Smckusick static void 188*36537Smckusick inittrap(dispaddr, dpaddr, endaddr, pcaddr, loopaddrp) 1895658Slinton union disply *dispaddr; 1905658Slinton struct disp *dpaddr; 1915658Slinton char *endaddr; 192*36537Smckusick union progcntr *pcaddr; 1935658Slinton char **loopaddrp; 1945658Slinton { 1955658Slinton kill(getpid(), SIGIOT); 1965658Slinton } 197