148108Sbostic /*-
2*62181Sbostic * Copyright (c) 1980, 1993
3*62181Sbostic * The Regents of the University of California. All rights reserved.
448108Sbostic *
548108Sbostic * %sccs.include.redist.c%
622151Sdist */
72079Smckusick
822151Sdist #ifndef lint
9*62181Sbostic static char copyright[] =
10*62181Sbostic "@(#) Copyright (c) 1980, 1993\n\
11*62181Sbostic The Regents of the University of California. All rights reserved.\n";
1248108Sbostic #endif /* not lint */
132079Smckusick
1422151Sdist #ifndef lint
15*62181Sbostic static char sccsid[] = "@(#)int.c 8.1 (Berkeley) 06/06/93";
1648108Sbostic #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
main(ac,av)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
inittrap(dispaddr,dpaddr,endaddr,pcaddr,loopaddrp)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