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