1 #ifndef lint
2 static char sccsid[] = "@(#)runpcs.c 4.6 04/25/85";
3 #endif
4 /*
5 *
6 * UNIX debugger
7 *
8 */
9
10 #include "defs.h"
11
12 extern MAP txtmap;
13
14 MSG NOFORK;
15 MSG ENDPCS;
16 MSG BADWAIT;
17
18 CHAR *lp;
19 ADDR sigint;
20 ADDR sigqit;
21
22 /* breakpoints */
23 BKPTR bkpthead;
24
25 REGLIST reglist[];
26
27 CHAR lastc;
28
29 INT fcor;
30 INT fsym;
31 STRING errflg;
32 INT errno;
33 INT signo;
34 INT sigcode;
35
36 L_INT dot;
37 STRING symfil;
38 INT wtflag;
39 L_INT pid;
40 L_INT expv;
41 INT adrflg;
42 L_INT loopcnt;
43
44
45
46
47
48 /* service routines for sub process control */
49
getsig(sig)50 getsig(sig)
51 { return(expr(0) ? expv : sig);
52 }
53
54 ADDR userpc = 1;
55
runpcs(runmode,execsig)56 runpcs(runmode,execsig)
57 {
58 INT rc;
59 REG BKPTR bkpt;
60 IF adrflg THEN userpc=dot; FI
61 printf("%s: running\n", symfil);
62
63 WHILE --loopcnt>=0
64 DO
65 #ifdef DEBUG
66 printf("\ncontinue %x %d\n",userpc,execsig);
67 #endif
68 IF runmode==SINGLE
69 THEN delbp(); /* hardware handles single-stepping */
70 ELSE /* continuing from a breakpoint is hard */
71 IF bkpt=scanbkpt(userpc)
72 THEN execbkpt(bkpt,execsig); execsig=0;
73 FI
74 setbp();
75 FI
76 ptrace(runmode,pid,userpc,execsig);
77 bpwait(); chkerr(); execsig=0; delbp(); readregs();
78
79 IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
80 THEN /* stopped by BPT instruction */
81 #ifdef DEBUG
82 printf("\n BPT code; '%s'%o'%o'%d",
83 bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
84 #endif
85 dot=bkpt->loc;
86 IF bkpt->flag==BKPTEXEC
87 ORF ((bkpt->flag=BKPTEXEC)
88 ANDF bkpt->comm[0]!=EOR
89 ANDF command(bkpt->comm,':')
90 ANDF --bkpt->count)
91 THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
92 ELSE bkpt->count=bkpt->initcnt; rc=1;
93 FI
94 ELSE execsig=signo; rc=0;
95 FI
96 OD
97 return(rc);
98 }
99
100 #define BPOUT 0
101 #define BPIN 1
102 INT bpstate = BPOUT;
103
endpcs()104 endpcs()
105 {
106 REG BKPTR bkptr;
107 IF pid
108 THEN ptrace(PT_KILL,pid,0,0); pid=0; userpc=1;
109 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
110 DO IF bkptr->flag
111 THEN bkptr->flag=BKPTSET;
112 FI
113 OD
114 FI
115 bpstate=BPOUT;
116 }
117
118 #ifdef VFORK
nullsig()119 nullsig()
120 {
121
122 }
123 #endif
124
setup()125 setup()
126 {
127 close(fsym); fsym = -1;
128 #ifndef VFORK
129 IF (pid = fork()) == 0
130 #else
131 IF (pid = vfork()) == 0
132 #endif
133 THEN ptrace(PT_TRACE_ME,0,0,0);
134 #ifdef VFORK
135 signal(SIGTRAP,nullsig);
136 #endif
137 signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
138 doexec(); exit(0);
139 ELIF pid == -1
140 THEN error(NOFORK);
141 ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0;
142 fsym=open(symfil,wtflag);
143 IF errflg
144 THEN printf("%s: cannot execute\n",symfil);
145 endpcs(); error(0);
146 FI
147 FI
148 bpstate=BPOUT;
149 }
150
execbkpt(bkptr,execsig)151 execbkpt(bkptr,execsig)
152 BKPTR bkptr;
153 {
154 #ifdef DEBUG
155 printf("exbkpt: %d\n",bkptr->count);
156 #endif
157 delbp();
158 ptrace(PT_STEP,pid,bkptr->loc,execsig);
159 bkptr->flag=BKPTSET;
160 bpwait(); chkerr(); readregs();
161 }
162
163
doexec()164 doexec()
165 {
166 STRING argl[MAXARG];
167 CHAR args[LINSIZ];
168 STRING p, *ap, filnam;
169 extern STRING environ;
170 ap=argl; p=args;
171 *ap++=symfil;
172 REP IF rdc()==EOR THEN break; FI
173 *ap = p;
174 /*
175 * First thing is to look for direction characters
176 * and get filename. Do not use up the args for filenames.
177 * Then get rid of spaces before next args.
178 */
179 IF lastc=='<'
180 THEN REP readchar(); PER lastc==SP ORF lastc==TB DONE
181 filnam = p;
182 WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='>'
183 DO *p++=lastc; readchar(); OD
184 *p = 0;
185 close(0);
186 IF open(filnam,0)<0
187 THEN printf("%s: cannot open\n",filnam); _exit(0);
188 FI
189 p = *ap;
190 ELIF lastc=='>'
191 THEN REP readchar(); PER lastc==SP ORF lastc==TB DONE
192 filnam = p;
193 WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='<'
194 DO *p++=lastc; readchar(); OD
195 *p = '\0';
196 close(1);
197 IF creat(filnam,0666)<0
198 THEN printf("%s: cannot create\n",filnam); _exit(0);
199 FI
200 p = *ap;
201 ELSE
202 WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='>' ANDF lastc!='<'
203 DO *p++=lastc; readchar(); OD
204 *p++ = '\0';
205 ap++;
206 FI
207 PER lastc!=EOR DONE
208 *ap++=0;
209 exect(symfil, argl, environ);
210 perror(symfil);
211 }
212
scanbkpt(adr)213 BKPTR scanbkpt(adr)
214 ADDR adr;
215 {
216 REG BKPTR bkptr;
217 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
218 DO IF bkptr->flag ANDF bkptr->loc==adr
219 THEN break;
220 FI
221 OD
222 return(bkptr);
223 }
224
delbp()225 delbp()
226 {
227 REG ADDR a;
228 REG BKPTR bkptr;
229 IF bpstate!=BPOUT
230 THEN
231 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
232 DO IF bkptr->flag
233 THEN a=bkptr->loc;
234 IF a < txtmap.e1 THEN
235 ptrace(PT_WRITE_I,pid,a,bkptr->ins);
236 ELSE
237 ptrace(PT_WRITE_D,pid,a,bkptr->ins);
238 FI
239 FI
240 OD
241 bpstate=BPOUT;
242 FI
243 }
244
245 #ifdef vax
246 #define SETBP(ins) (BPT | ((ins) &~ 0xFF))
247 #endif
248
setbp()249 setbp()
250 {
251 REG ADDR a;
252 REG BKPTR bkptr;
253
254 IF bpstate!=BPIN
255 THEN
256 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
257 DO IF bkptr->flag
258 THEN a = bkptr->loc;
259 IF a < txtmap.e1 THEN
260 bkptr->ins = ptrace(PT_READ_I, pid, a, 0);
261 ptrace(PT_WRITE_I, pid, a, SETBP(bkptr->ins));
262 ELSE
263 bkptr->ins = ptrace(PT_READ_D, pid, a, 0);
264 ptrace(PT_WRITE_D, pid, a, SETBP(bkptr->ins));
265 FI
266 IF errno
267 THEN prints("cannot set breakpoint: ");
268 psymoff(bkptr->loc,ISYM,"\n");
269 FI
270 FI
271 OD
272 bpstate=BPIN;
273 FI
274 }
275
bpwait()276 bpwait()
277 {
278 REG ADDR w;
279 ADDR stat;
280
281 signal(SIGINT, 1);
282 WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
283 signal(SIGINT,sigint);
284 IF w == -1
285 THEN pid=0;
286 errflg=BADWAIT;
287 ELIF (stat & 0177) != 0177
288 THEN sigcode = 0;
289 IF signo = stat&0177
290 THEN sigprint();
291 FI
292 IF stat&0200
293 THEN prints(" - core dumped");
294 close(fcor);
295 setcor();
296 FI
297 pid=0;
298 errflg=ENDPCS;
299 ELSE signo = stat>>8;
300 sigcode = ptrace(PT_READ_U, pid, &((struct user *)0)->u_code, 0);
301 IF signo!=SIGTRAP
302 THEN sigprint();
303 ELSE signo=0;
304 FI
305 flushbuf();
306 FI
307 }
308
readregs()309 readregs()
310 {
311 /*get REG values from pcs*/
312 REG i;
313 FOR i=24; --i>=0;
314 DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
315 ptrace(PT_READ_U, pid, reglist[i].roffs, 0);
316 OD
317 userpc= *(ADDR *)(((ADDR)&u)+PC);
318 }
319
320
321