xref: /original-bsd/usr.bin/pascal/px/int.c (revision 0eaa7944)
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.1 (Berkeley) 06/05/85";
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 union progcntr *pcaddrp;	/* address of interpreter frame address */
40 
41 main(ac,av)
42 
43 	int	ac;
44 	char	**av;
45 
46 {
47 	register char *objprog, *file;
48 	char *name;
49 	register long bytesread, bytestoread, block;
50 	register FILE *prog;
51 	struct	 pxhdr pxhd;
52 #	define	 pipe 3
53 
54 	/*
55 	 * Initialize everything
56 	 */
57 	_argc = ac;
58 	_argv = av;
59 	_nodump = FALSE;
60 
61 	/*
62 	 * Determine how PX was invoked, and how to process the program
63 	 */
64 	file = _argv[1];
65 	if (!strcmp(_argv[0], "pdx")) {
66 		_mode = PDX;
67 		_argv += 2; _argc -= 2;
68 		name = _argv[0];
69 	} else if (!strcmp(_argv[0], "pix")) {
70 		_mode = PIX;
71 		_argv++; _argc--;
72 		name = _argv[0];
73 	} else if (!strcmp(_argv[0], "pipe")) {
74 		_mode = PIPE;
75 		file = "PIPE";
76 		_argv++; _argc--;
77 		name = _argv[0];
78 	} else {
79 		_mode = PX;
80 		if (_argc <= 1)
81 			file = "obj";
82 		name = file;
83 	}
84 
85 	/*
86 	 * kludge to check for old style objs.
87 	 */
88 	if (_mode == PX && !strcmp(file, "-")) {
89 		fprintf(stderr, "%s is obsolete and must be recompiled\n",
90 		    _argv[0]);
91 		exit(1);
92 	}
93 	/*
94 	 * Process program header information
95 	 */
96 	if (_mode == PIPE) {
97 		read(pipe,&pxhd,sizeof(struct pxhdr));
98 	} else {
99 		prog = fopen(file,"r");
100 		if (prog == NULL) {
101 			perror(file);
102 			exit(1);
103 		}
104 		fread(&pxhd,sizeof(struct pxhdr),1,prog);
105 		if (pxhd.magicnum != MAGICNUM) {
106 			fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0);
107 			fread(&pxhd,sizeof(struct pxhdr),1,prog);
108 		}
109 	}
110 	if (pxhd.magicnum != MAGICNUM) {
111 		fprintf(stderr,"%s is not a Pascal interpreter file\n",name);
112 		exit(1);
113 	}
114 	if (pxhd.maketime < createtime) {
115 		fprintf(stderr,"%s is obsolete and must be recompiled\n",name);
116 		exit(1);
117 	}
118 
119 	/*
120 	 * Load program into memory
121 	 */
122 	objprog = malloc((int)pxhd.objsize);
123 	if (_mode == PIPE) {
124 		bytestoread = pxhd.objsize;
125 		bytesread = 0;
126 		do	{
127 			block = read(pipe,(int)(objprog+bytesread),bytestoread);
128 			if (block > 0) {
129 				bytesread += block;
130 				bytestoread -= block;
131 			}
132 		} while (block > 0);
133 	} else {
134 		bytesread = fread(objprog,1,(int)pxhd.objsize,prog);
135 		fclose(prog);
136 	}
137 	if (bytesread != pxhd.objsize) {
138 		fprintf(stderr,"Read error occurred while loading %s\n",file);
139 		exit(1);
140 	}
141 	if (_mode == PIX)
142 		fputs("Execution begins...\n",stderr);
143 	/*
144 	 * set interpreter to catch expected signals and begin interpretation
145 	 */
146 	signal(SIGILL,syserr);
147 	signal(SIGBUS,syserr);
148 	signal(SIGSYS,syserr);
149 	if (signal(SIGINT,SIG_IGN) != SIG_IGN)
150 		signal(SIGINT,intr);
151 	signal(SIGSEGV,memsize);
152 	signal(SIGFPE,EXCEPT);
153 	signal(SIGTRAP,liberr);
154 
155 	/*
156 	 * See if we're being watched by the debugger, if so set a trap.
157 	 */
158 	if (_mode == PDX || (_mode == PIX && pxhd.symtabsize > 0)) {
159 		inittrap(&_display, &_dp, objprog, &pcaddrp, loopaddr);
160 	}
161 
162 	/*
163 	 * do it
164 	 */
165 	interpreter(objprog);
166 	/*
167 	 * reset signals, deallocate memory, and exit normally
168 	 */
169 	signal(SIGINT,SIG_IGN);
170 	signal(SIGSEGV,SIG_DFL);
171 	signal(SIGFPE,SIG_DFL);
172 	signal(SIGTRAP,SIG_DFL);
173 	signal(SIGILL,SIG_DFL);
174 	signal(SIGBUS,SIG_DFL);
175 	signal(SIGSYS,SIG_DFL);
176 	PFLUSH();
177 	psexit(0);
178 }
179 
180 /*
181  * Generate an IOT trap to tell the debugger that the object code
182  * has been read in.  Parameters are there for debugger to look at,
183  * not the procedure.
184  */
185 
186 static inittrap(dispaddr, dpaddr, endaddr, pcaddrp, loopaddrp)
187 union disply *dispaddr;
188 struct disp *dpaddr;
189 char *endaddr;
190 union progcntr **pcaddrp;
191 char **loopaddrp;
192 {
193 	kill(getpid(), SIGIOT);
194 }
195