xref: /original-bsd/usr.bin/pascal/px/int.c (revision c3e32dec)
1 /*-
2  * Copyright (c) 1980, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char copyright[] =
10 "@(#) Copyright (c) 1980, 1993\n\
11 	The Regents of the University of California.  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)int.c	8.1 (Berkeley) 06/06/93";
16 #endif /* not lint */
17 
18 /*
19  * px - interpreter for Berkeley Pascal
20  * Version 3.0 Winter 1979
21  *
22  * Original version for the PDP 11/70 authored by:
23  * Bill Joy, Charles Haley, Ken Thompson
24  *
25  * Rewritten for VAX 11/780 by Kirk McKusick
26  */
27 
28 #include	<signal.h>
29 #include	"whoami.h"
30 #include	"vars.h"
31 #include	"libpc.h"
32 #include	"objfmt.h"
33 
34 /*
35  * New stuff for pdx
36  */
37 
38 extern char *end;
39 extern loopaddr();
40 extern union progcntr pdx_pc;	/* address of interpreter program cntr */
41 static void inittrap();
42 
43 main(ac,av)
44 
45 	int	ac;
46 	char	**av;
47 
48 {
49 	register char *objprog, *file;
50 	char *name;
51 	register long bytesread, bytestoread, block;
52 	register FILE *prog;
53 	struct	 pxhdr pxhd;
54 #	define	 pipe 3
55 
56 	/*
57 	 * Initialize everything
58 	 */
59 	_argc = ac;
60 	_argv = av;
61 	_nodump = FALSE;
62 
63 	/*
64 	 * Determine how PX was invoked, and how to process the program
65 	 */
66 	file = _argv[1];
67 	if (!strcmp(_argv[0], "pdx")) {
68 		_mode = PDX;
69 		_argv += 2; _argc -= 2;
70 		name = _argv[0];
71 	} else if (!strcmp(_argv[0], "pix")) {
72 		_mode = PIX;
73 		_argv++; _argc--;
74 		name = _argv[0];
75 	} else if (!strcmp(_argv[0], "pipe")) {
76 		_mode = PIPE;
77 		file = "PIPE";
78 		_argv++; _argc--;
79 		name = _argv[0];
80 	} else {
81 		_mode = PX;
82 		if (_argc <= 1)
83 			file = "obj";
84 		name = file;
85 	}
86 
87 	/*
88 	 * kludge to check for old style objs.
89 	 */
90 	if (_mode == PX && !strcmp(file, "-")) {
91 		fprintf(stderr, "%s is obsolete and must be recompiled\n",
92 		    _argv[0]);
93 		exit(1);
94 	}
95 	/*
96 	 * Process program header information
97 	 */
98 	if (_mode == PIPE) {
99 		read(pipe,&pxhd,sizeof(struct pxhdr));
100 	} else {
101 		prog = fopen(file,"r");
102 		if (prog == NULL) {
103 			perror(file);
104 			exit(1);
105 		}
106 		fread(&pxhd,sizeof(struct pxhdr),1,prog);
107 		if (pxhd.magicnum != MAGICNUM) {
108 			fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0);
109 			fread(&pxhd,sizeof(struct pxhdr),1,prog);
110 		}
111 	}
112 	if (pxhd.magicnum != MAGICNUM) {
113 		fprintf(stderr,"%s is not a Pascal interpreter file\n",name);
114 		exit(1);
115 	}
116 	if (pxhd.maketime < createtime) {
117 		fprintf(stderr,"%s is obsolete and must be recompiled\n",name);
118 		exit(1);
119 	}
120 
121 	/*
122 	 * Load program into memory
123 	 */
124 	objprog = malloc((int)pxhd.objsize);
125 	if (_mode == PIPE) {
126 		bytestoread = pxhd.objsize;
127 		bytesread = 0;
128 		do	{
129 			block = read(pipe,(int)(objprog+bytesread),bytestoread);
130 			if (block > 0) {
131 				bytesread += block;
132 				bytestoread -= block;
133 			}
134 		} while (block > 0);
135 	} else {
136 		bytesread = fread(objprog,1,(int)pxhd.objsize,prog);
137 		fclose(prog);
138 	}
139 	if (bytesread != pxhd.objsize) {
140 		fprintf(stderr,"Read error occurred while loading %s\n",file);
141 		exit(1);
142 	}
143 	if (_mode == PIX)
144 		fputs("Execution begins...\n",stderr);
145 	/*
146 	 * set interpreter to catch expected signals and begin interpretation
147 	 */
148 	signal(SIGILL,syserr);
149 	signal(SIGBUS,syserr);
150 	signal(SIGSYS,syserr);
151 	if (signal(SIGINT,SIG_IGN) != SIG_IGN)
152 		signal(SIGINT,intr);
153 	signal(SIGSEGV,memsize);
154 	signal(SIGFPE,EXCEPT);
155 	signal(SIGTRAP,liberr);
156 
157 	/*
158 	 * See if we're being watched by the debugger, if so set a trap.
159 	 */
160 	if (_mode == PDX || (_mode == PIX && pxhd.symtabsize > 0)) {
161 		inittrap(&_display, &_dp, objprog, &pdx_pc, loopaddr);
162 	}
163 
164 	/*
165 	 * do it
166 	 */
167 	interpreter(objprog);
168 	/*
169 	 * reset signals, deallocate memory, and exit normally
170 	 */
171 	signal(SIGINT,SIG_IGN);
172 	signal(SIGSEGV,SIG_DFL);
173 	signal(SIGFPE,SIG_DFL);
174 	signal(SIGTRAP,SIG_DFL);
175 	signal(SIGILL,SIG_DFL);
176 	signal(SIGBUS,SIG_DFL);
177 	signal(SIGSYS,SIG_DFL);
178 	PFLUSH();
179 	psexit(0);
180 }
181 
182 /*
183  * Generate an IOT trap to tell the debugger that the object code
184  * has been read in.  Parameters are there for debugger to look at,
185  * not the procedure.
186  */
187 
188 static void
189 inittrap(dispaddr, dpaddr, endaddr, pcaddr, loopaddrp)
190 union disply *dispaddr;
191 struct disp *dpaddr;
192 char *endaddr;
193 union progcntr *pcaddr;
194 char **loopaddrp;
195 {
196 	kill(getpid(), SIGIOT);
197 }
198