xref: /csrg-svn/usr.bin/pascal/px/int.c (revision 22151)
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