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
main(ac,av)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
inittrap(dispaddr,dpaddr,endaddr,pcaddr,loopaddrp)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