1*48108Sbostic /*- 2*48108Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48108Sbostic * All rights reserved. 4*48108Sbostic * 5*48108Sbostic * %sccs.include.redist.c% 622151Sdist */ 72079Smckusick 822151Sdist #ifndef lint 922151Sdist char copyright[] = 10*48108Sbostic "@(#) Copyright (c) 1980 The Regents of the University of California.\n\ 1122151Sdist All rights reserved.\n"; 12*48108Sbostic #endif /* not lint */ 132079Smckusick 1422151Sdist #ifndef lint 15*48108Sbostic static char sccsid[] = "@(#)int.c 5.3 (Berkeley) 04/16/91"; 16*48108Sbostic #endif /* not lint */ 1722151Sdist 182079Smckusick /* 192079Smckusick * px - interpreter for Berkeley Pascal 202079Smckusick * Version 3.0 Winter 1979 212079Smckusick * 222079Smckusick * Original version for the PDP 11/70 authored by: 232079Smckusick * Bill Joy, Charles Haley, Ken Thompson 242079Smckusick * 252079Smckusick * Rewritten for VAX 11/780 by Kirk McKusick 262079Smckusick */ 272079Smckusick 282079Smckusick #include <signal.h> 292950Smckusic #include "whoami.h" 302079Smckusick #include "vars.h" 315678Smckusic #include "libpc.h" 322079Smckusick #include "objfmt.h" 332079Smckusick 345658Slinton /* 355658Slinton * New stuff for pdx 365658Slinton */ 375658Slinton 385658Slinton extern char *end; 395658Slinton extern loopaddr(); 4036537Smckusick extern union progcntr pdx_pc; /* address of interpreter program cntr */ 4136537Smckusick static void inittrap(); 425658Slinton 432079Smckusick main(ac,av) 442079Smckusick 452950Smckusic int ac; 462950Smckusic char **av; 472079Smckusick 482079Smckusick { 492950Smckusic register char *objprog, *file; 505661Smckusic char *name; 513910Smckusic register long bytesread, bytestoread, block; 522950Smckusic register FILE *prog; 532950Smckusic struct pxhdr pxhd; 542950Smckusic # define pipe 3 552079Smckusick 562950Smckusic /* 572950Smckusic * Initialize everything 582950Smckusic */ 592950Smckusic _argc = ac; 602950Smckusic _argv = av; 612950Smckusic _nodump = FALSE; 622079Smckusick 632950Smckusic /* 642950Smckusic * Determine how PX was invoked, and how to process the program 652950Smckusic */ 665658Slinton file = _argv[1]; 675658Slinton if (!strcmp(_argv[0], "pdx")) { 685658Slinton _mode = PDX; 695658Slinton _argv += 2; _argc -= 2; 705661Smckusic name = _argv[0]; 715658Slinton } else if (!strcmp(_argv[0], "pix")) { 722950Smckusic _mode = PIX; 735658Slinton _argv++; _argc--; 745661Smckusic name = _argv[0]; 755658Slinton } else if (!strcmp(_argv[0], "pipe")) { 762950Smckusic _mode = PIPE; 775658Slinton file = "PIPE"; 785658Slinton _argv++; _argc--; 795661Smckusic name = _argv[0]; 803910Smckusic } else { 815658Slinton _mode = PX; 825658Slinton if (_argc <= 1) 835658Slinton file = "obj"; 845661Smckusic name = file; 853910Smckusic } 862079Smckusick 872950Smckusic /* 885744Smckusic * kludge to check for old style objs. 895744Smckusic */ 905744Smckusic if (_mode == PX && !strcmp(file, "-")) { 915744Smckusic fprintf(stderr, "%s is obsolete and must be recompiled\n", 925744Smckusic _argv[0]); 935744Smckusic exit(1); 945744Smckusic } 955744Smckusic /* 962950Smckusic * Process program header information 972950Smckusic */ 983910Smckusic if (_mode == PIPE) { 992950Smckusic read(pipe,&pxhd,sizeof(struct pxhdr)); 1003910Smckusic } else { 1012950Smckusic prog = fopen(file,"r"); 1023910Smckusic if (prog == NULL) { 1032950Smckusic perror(file); 1042950Smckusic exit(1); 1053910Smckusic } 1062950Smckusic fread(&pxhd,sizeof(struct pxhdr),1,prog); 1075658Slinton if (pxhd.magicnum != MAGICNUM) { 1085658Slinton fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0); 1095658Slinton fread(&pxhd,sizeof(struct pxhdr),1,prog); 1105658Slinton } 1113910Smckusic } 1125658Slinton if (pxhd.magicnum != MAGICNUM) { 1135661Smckusic fprintf(stderr,"%s is not a Pascal interpreter file\n",name); 1145658Slinton exit(1); 1155658Slinton } 1163910Smckusic if (pxhd.maketime < createtime) { 1175661Smckusic fprintf(stderr,"%s is obsolete and must be recompiled\n",name); 1182079Smckusick exit(1); 1193910Smckusic } 1202079Smckusick 1212950Smckusic /* 1222950Smckusic * Load program into memory 1232950Smckusic */ 1242950Smckusic objprog = malloc((int)pxhd.objsize); 1253910Smckusic if (_mode == PIPE) { 1263910Smckusic bytestoread = pxhd.objsize; 1272950Smckusic bytesread = 0; 1283910Smckusic do { 1293910Smckusic block = read(pipe,(int)(objprog+bytesread),bytestoread); 1303910Smckusic if (block > 0) { 1313910Smckusic bytesread += block; 1323910Smckusic bytestoread -= block; 1332950Smckusic } 1343910Smckusic } while (block > 0); 1353910Smckusic } else { 1362950Smckusic bytesread = fread(objprog,1,(int)pxhd.objsize,prog); 1372950Smckusic fclose(prog); 1383910Smckusic } 1393910Smckusic if (bytesread != pxhd.objsize) { 1402950Smckusic fprintf(stderr,"Read error occurred while loading %s\n",file); 1412950Smckusic exit(1); 1423910Smckusic } 1432079Smckusick if (_mode == PIX) 1442950Smckusic fputs("Execution begins...\n",stderr); 1452950Smckusic /* 1462950Smckusic * set interpreter to catch expected signals and begin interpretation 1472950Smckusic */ 1482950Smckusic signal(SIGILL,syserr); 1492950Smckusic signal(SIGBUS,syserr); 1502950Smckusic signal(SIGSYS,syserr); 1512950Smckusic if (signal(SIGINT,SIG_IGN) != SIG_IGN) 1522950Smckusic signal(SIGINT,intr); 1532950Smckusic signal(SIGSEGV,memsize); 1545678Smckusic signal(SIGFPE,EXCEPT); 1552950Smckusic signal(SIGTRAP,liberr); 1565658Slinton 1572950Smckusic /* 1585658Slinton * See if we're being watched by the debugger, if so set a trap. 1595658Slinton */ 1605658Slinton if (_mode == PDX || (_mode == PIX && pxhd.symtabsize > 0)) { 16136537Smckusick inittrap(&_display, &_dp, objprog, &pdx_pc, loopaddr); 1625658Slinton } 1635658Slinton 1645658Slinton /* 1652950Smckusic * do it 1662950Smckusic */ 1672950Smckusic interpreter(objprog); 1682950Smckusic /* 1692950Smckusic * reset signals, deallocate memory, and exit normally 1702950Smckusic */ 1712950Smckusic signal(SIGINT,SIG_IGN); 1722950Smckusic signal(SIGSEGV,SIG_DFL); 1732950Smckusic signal(SIGFPE,SIG_DFL); 1742950Smckusic signal(SIGTRAP,SIG_DFL); 1752950Smckusic signal(SIGILL,SIG_DFL); 1762950Smckusic signal(SIGBUS,SIG_DFL); 1772950Smckusic signal(SIGSYS,SIG_DFL); 1782950Smckusic PFLUSH(); 1792950Smckusic psexit(0); 1802079Smckusick } 1815658Slinton 1825658Slinton /* 1835658Slinton * Generate an IOT trap to tell the debugger that the object code 1845658Slinton * has been read in. Parameters are there for debugger to look at, 1855658Slinton * not the procedure. 1865658Slinton */ 1875658Slinton 18836537Smckusick static void 18936537Smckusick inittrap(dispaddr, dpaddr, endaddr, pcaddr, loopaddrp) 1905658Slinton union disply *dispaddr; 1915658Slinton struct disp *dpaddr; 1925658Slinton char *endaddr; 19336537Smckusick union progcntr *pcaddr; 1945658Slinton char **loopaddrp; 1955658Slinton { 1965658Slinton kill(getpid(), SIGIOT); 1975658Slinton } 198