1*22151Sdist /* 2*22151Sdist * Copyright (c) 1980 Regents of the University of California. 3*22151Sdist * All rights reserved. The Berkeley software License Agreement 4*22151Sdist * specifies the terms and conditions for redistribution. 5*22151Sdist */ 62079Smckusick 7*22151Sdist #ifndef lint 8*22151Sdist char copyright[] = 9*22151Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10*22151Sdist All rights reserved.\n"; 11*22151Sdist #endif not lint 122079Smckusick 13*22151Sdist #ifndef lint 14*22151Sdist static char sccsid[] = "@(#)int.c 5.1 (Berkeley) 06/05/85"; 15*22151Sdist #endif not lint 16*22151Sdist 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(); 395658Slinton union progcntr *pcaddrp; /* address of interpreter frame address */ 405658Slinton 412079Smckusick main(ac,av) 422079Smckusick 432950Smckusic int ac; 442950Smckusic char **av; 452079Smckusick 462079Smckusick { 472950Smckusic register char *objprog, *file; 485661Smckusic char *name; 493910Smckusic register long bytesread, bytestoread, block; 502950Smckusic register FILE *prog; 512950Smckusic struct pxhdr pxhd; 522950Smckusic # define pipe 3 532079Smckusick 542950Smckusic /* 552950Smckusic * Initialize everything 562950Smckusic */ 572950Smckusic _argc = ac; 582950Smckusic _argv = av; 592950Smckusic _nodump = FALSE; 602079Smckusick 612950Smckusic /* 622950Smckusic * Determine how PX was invoked, and how to process the program 632950Smckusic */ 645658Slinton file = _argv[1]; 655658Slinton if (!strcmp(_argv[0], "pdx")) { 665658Slinton _mode = PDX; 675658Slinton _argv += 2; _argc -= 2; 685661Smckusic name = _argv[0]; 695658Slinton } else if (!strcmp(_argv[0], "pix")) { 702950Smckusic _mode = PIX; 715658Slinton _argv++; _argc--; 725661Smckusic name = _argv[0]; 735658Slinton } else if (!strcmp(_argv[0], "pipe")) { 742950Smckusic _mode = PIPE; 755658Slinton file = "PIPE"; 765658Slinton _argv++; _argc--; 775661Smckusic name = _argv[0]; 783910Smckusic } else { 795658Slinton _mode = PX; 805658Slinton if (_argc <= 1) 815658Slinton file = "obj"; 825661Smckusic name = file; 833910Smckusic } 842079Smckusick 852950Smckusic /* 865744Smckusic * kludge to check for old style objs. 875744Smckusic */ 885744Smckusic if (_mode == PX && !strcmp(file, "-")) { 895744Smckusic fprintf(stderr, "%s is obsolete and must be recompiled\n", 905744Smckusic _argv[0]); 915744Smckusic exit(1); 925744Smckusic } 935744Smckusic /* 942950Smckusic * Process program header information 952950Smckusic */ 963910Smckusic if (_mode == PIPE) { 972950Smckusic read(pipe,&pxhd,sizeof(struct pxhdr)); 983910Smckusic } else { 992950Smckusic prog = fopen(file,"r"); 1003910Smckusic if (prog == NULL) { 1012950Smckusic perror(file); 1022950Smckusic exit(1); 1033910Smckusic } 1042950Smckusic fread(&pxhd,sizeof(struct pxhdr),1,prog); 1055658Slinton if (pxhd.magicnum != MAGICNUM) { 1065658Slinton fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0); 1075658Slinton fread(&pxhd,sizeof(struct pxhdr),1,prog); 1085658Slinton } 1093910Smckusic } 1105658Slinton if (pxhd.magicnum != MAGICNUM) { 1115661Smckusic fprintf(stderr,"%s is not a Pascal interpreter file\n",name); 1125658Slinton exit(1); 1135658Slinton } 1143910Smckusic if (pxhd.maketime < createtime) { 1155661Smckusic fprintf(stderr,"%s is obsolete and must be recompiled\n",name); 1162079Smckusick exit(1); 1173910Smckusic } 1182079Smckusick 1192950Smckusic /* 1202950Smckusic * Load program into memory 1212950Smckusic */ 1222950Smckusic objprog = malloc((int)pxhd.objsize); 1233910Smckusic if (_mode == PIPE) { 1243910Smckusic bytestoread = pxhd.objsize; 1252950Smckusic bytesread = 0; 1263910Smckusic do { 1273910Smckusic block = read(pipe,(int)(objprog+bytesread),bytestoread); 1283910Smckusic if (block > 0) { 1293910Smckusic bytesread += block; 1303910Smckusic bytestoread -= block; 1312950Smckusic } 1323910Smckusic } while (block > 0); 1333910Smckusic } else { 1342950Smckusic bytesread = fread(objprog,1,(int)pxhd.objsize,prog); 1352950Smckusic fclose(prog); 1363910Smckusic } 1373910Smckusic if (bytesread != pxhd.objsize) { 1382950Smckusic fprintf(stderr,"Read error occurred while loading %s\n",file); 1392950Smckusic exit(1); 1403910Smckusic } 1412079Smckusick if (_mode == PIX) 1422950Smckusic fputs("Execution begins...\n",stderr); 1432950Smckusic /* 1442950Smckusic * set interpreter to catch expected signals and begin interpretation 1452950Smckusic */ 1462950Smckusic signal(SIGILL,syserr); 1472950Smckusic signal(SIGBUS,syserr); 1482950Smckusic signal(SIGSYS,syserr); 1492950Smckusic if (signal(SIGINT,SIG_IGN) != SIG_IGN) 1502950Smckusic signal(SIGINT,intr); 1512950Smckusic signal(SIGSEGV,memsize); 1525678Smckusic signal(SIGFPE,EXCEPT); 1532950Smckusic signal(SIGTRAP,liberr); 1545658Slinton 1552950Smckusic /* 1565658Slinton * See if we're being watched by the debugger, if so set a trap. 1575658Slinton */ 1585658Slinton if (_mode == PDX || (_mode == PIX && pxhd.symtabsize > 0)) { 1595658Slinton inittrap(&_display, &_dp, objprog, &pcaddrp, loopaddr); 1605658Slinton } 1615658Slinton 1625658Slinton /* 1632950Smckusic * do it 1642950Smckusic */ 1652950Smckusic interpreter(objprog); 1662950Smckusic /* 1672950Smckusic * reset signals, deallocate memory, and exit normally 1682950Smckusic */ 1692950Smckusic signal(SIGINT,SIG_IGN); 1702950Smckusic signal(SIGSEGV,SIG_DFL); 1712950Smckusic signal(SIGFPE,SIG_DFL); 1722950Smckusic signal(SIGTRAP,SIG_DFL); 1732950Smckusic signal(SIGILL,SIG_DFL); 1742950Smckusic signal(SIGBUS,SIG_DFL); 1752950Smckusic signal(SIGSYS,SIG_DFL); 1762950Smckusic PFLUSH(); 1772950Smckusic psexit(0); 1782079Smckusick } 1795658Slinton 1805658Slinton /* 1815658Slinton * Generate an IOT trap to tell the debugger that the object code 1825658Slinton * has been read in. Parameters are there for debugger to look at, 1835658Slinton * not the procedure. 1845658Slinton */ 1855658Slinton 1865658Slinton static inittrap(dispaddr, dpaddr, endaddr, pcaddrp, loopaddrp) 1875658Slinton union disply *dispaddr; 1885658Slinton struct disp *dpaddr; 1895658Slinton char *endaddr; 1905658Slinton union progcntr **pcaddrp; 1915658Slinton char **loopaddrp; 1925658Slinton { 1935658Slinton kill(getpid(), SIGIOT); 1945658Slinton } 195