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