Commit | Line | Data |
---|---|---|
3e8db0a8 DF |
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 | |
2917d4fc | 12 | |
3e8db0a8 DF |
13 | #ifndef lint |
14 | static char sccsid[] = "@(#)int.c 5.1 (Berkeley) %G%"; | |
15 | #endif not lint | |
2917d4fc KM |
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> | |
9a92014d | 28 | #include "whoami.h" |
2917d4fc | 29 | #include "vars.h" |
8fe8ed0d | 30 | #include "libpc.h" |
2917d4fc KM |
31 | #include "objfmt.h" |
32 | ||
b4466be6 ML |
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 | ||
2917d4fc KM |
41 | main(ac,av) |
42 | ||
9a92014d KM |
43 | int ac; |
44 | char **av; | |
2917d4fc KM |
45 | |
46 | { | |
9a92014d | 47 | register char *objprog, *file; |
e111a523 | 48 | char *name; |
842d41c9 | 49 | register long bytesread, bytestoread, block; |
9a92014d KM |
50 | register FILE *prog; |
51 | struct pxhdr pxhd; | |
52 | # define pipe 3 | |
2917d4fc | 53 | |
9a92014d KM |
54 | /* |
55 | * Initialize everything | |
56 | */ | |
57 | _argc = ac; | |
58 | _argv = av; | |
59 | _nodump = FALSE; | |
2917d4fc | 60 | \f |
9a92014d KM |
61 | /* |
62 | * Determine how PX was invoked, and how to process the program | |
63 | */ | |
b4466be6 ML |
64 | file = _argv[1]; |
65 | if (!strcmp(_argv[0], "pdx")) { | |
66 | _mode = PDX; | |
67 | _argv += 2; _argc -= 2; | |
e111a523 | 68 | name = _argv[0]; |
b4466be6 | 69 | } else if (!strcmp(_argv[0], "pix")) { |
9a92014d | 70 | _mode = PIX; |
b4466be6 | 71 | _argv++; _argc--; |
e111a523 | 72 | name = _argv[0]; |
b4466be6 | 73 | } else if (!strcmp(_argv[0], "pipe")) { |
9a92014d | 74 | _mode = PIPE; |
b4466be6 ML |
75 | file = "PIPE"; |
76 | _argv++; _argc--; | |
e111a523 | 77 | name = _argv[0]; |
842d41c9 | 78 | } else { |
b4466be6 ML |
79 | _mode = PX; |
80 | if (_argc <= 1) | |
81 | file = "obj"; | |
e111a523 | 82 | name = file; |
842d41c9 | 83 | } |
2917d4fc | 84 | \f |
fa68e687 KM |
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 | } | |
9a92014d KM |
93 | /* |
94 | * Process program header information | |
95 | */ | |
842d41c9 | 96 | if (_mode == PIPE) { |
9a92014d | 97 | read(pipe,&pxhd,sizeof(struct pxhdr)); |
842d41c9 | 98 | } else { |
9a92014d | 99 | prog = fopen(file,"r"); |
842d41c9 | 100 | if (prog == NULL) { |
9a92014d KM |
101 | perror(file); |
102 | exit(1); | |
842d41c9 | 103 | } |
9a92014d | 104 | fread(&pxhd,sizeof(struct pxhdr),1,prog); |
b4466be6 ML |
105 | if (pxhd.magicnum != MAGICNUM) { |
106 | fseek(prog,(long)(HEADER_BYTES-sizeof(struct pxhdr)),0); | |
107 | fread(&pxhd,sizeof(struct pxhdr),1,prog); | |
108 | } | |
842d41c9 KM |
109 | } |
110 | if (pxhd.magicnum != MAGICNUM) { | |
e111a523 | 111 | fprintf(stderr,"%s is not a Pascal interpreter file\n",name); |
2917d4fc | 112 | exit(1); |
842d41c9 | 113 | } |
b4466be6 | 114 | if (pxhd.maketime < createtime) { |
e111a523 | 115 | fprintf(stderr,"%s is obsolete and must be recompiled\n",name); |
b4466be6 ML |
116 | exit(1); |
117 | } | |
2917d4fc | 118 | \f |
9a92014d KM |
119 | /* |
120 | * Load program into memory | |
121 | */ | |
122 | objprog = malloc((int)pxhd.objsize); | |
842d41c9 KM |
123 | if (_mode == PIPE) { |
124 | bytestoread = pxhd.objsize; | |
9a92014d | 125 | bytesread = 0; |
842d41c9 KM |
126 | do { |
127 | block = read(pipe,(int)(objprog+bytesread),bytestoread); | |
128 | if (block > 0) { | |
129 | bytesread += block; | |
130 | bytestoread -= block; | |
9a92014d | 131 | } |
842d41c9 KM |
132 | } while (block > 0); |
133 | } else { | |
9a92014d KM |
134 | bytesread = fread(objprog,1,(int)pxhd.objsize,prog); |
135 | fclose(prog); | |
842d41c9 KM |
136 | } |
137 | if (bytesread != pxhd.objsize) { | |
9a92014d KM |
138 | fprintf(stderr,"Read error occurred while loading %s\n",file); |
139 | exit(1); | |
842d41c9 | 140 | } |
2917d4fc | 141 | if (_mode == PIX) |
9a92014d KM |
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); | |
8fe8ed0d | 152 | signal(SIGFPE,EXCEPT); |
9a92014d | 153 | signal(SIGTRAP,liberr); |
b4466be6 ML |
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 | ||
9a92014d KM |
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(); | |
9a92014d | 177 | psexit(0); |
2917d4fc | 178 | } |
b4466be6 ML |
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 | } |