1 /*-
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.proprietary.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)pcs.c 5.6 (Berkeley) 04/04/91";
10 #endif /* not lint */
11
12 /*
13 * adb - subprocess control
14 */
15
16 #include "defs.h"
17 #include "bkpt.h"
18 #include <machine/reg.h> /* for getpc() *//* XXX */
19 #include <sys/file.h>
20 #include <sys/ptrace.h>
21 #include <sys/wait.h>
22
23 extern char NOBKPT[];
24 extern char SZBKPT[];
25 extern char EXBKPT[];
26 extern char NOPCS[];
27 extern char BADMOD[];
28 extern char NOFORK[];
29 extern char ENDPCS[];
30 extern char BADWAIT[];
31
32 struct bkpt *bkpthead; /* head of breakpoint list */
33
34 static long runcount; /* number of times to loop past breakpoints */
35
36 /* bpstate remembers whether we have installed the breakpoints */
37 static enum { BPOUT, BPIN } bpstate;
38
39 char *malloc();
40
41 /* run modes */
42 #define CONTINUOUS 0
43 #define SINGLESTEP 1
44
45 /* sub process control */
46
subpcs(modif)47 subpcs(modif)
48 int modif;
49 {
50 register int check;
51 register struct bkpt *bp;
52 int execsig, runmode;
53 char *comptr;
54
55 switch (modif) {
56
57 case 'd':
58 /* delete breakpoint */
59 if ((bp = scanbkpt(dot)) == NULL)
60 error(NOBKPT);
61 bp->state = BKPT_FREE;
62 return;
63
64 case 'D':
65 /* delete all breapoints */
66 for (bp = bkpthead; bp != NULL; bp = bp->next)
67 bp->state = BKPT_FREE;
68 return;
69
70 case 'b':
71 case 'B':
72 /* set breakpoint */
73 if ((bp = scanbkpt(dot)) == NULL) {
74 /* find a free one, or make one */
75 for (bp = bkpthead; bp != NULL; bp = bp->next)
76 if (bp->state == BKPT_FREE)
77 break;
78 if (bp == NULL) {
79 bp = (struct bkpt *)malloc(sizeof *bp);
80 if (bp == NULL)
81 error(EXBKPT);
82 bp->next = bkpthead;
83 bkpthead = bp;
84 }
85 }
86 bp->loc = dot;
87 bp->initcnt = bp->count = ecount;
88 bp->state = BKPT_SET;
89 check = MAX_BKPTCOM - 1;
90 comptr = bp->comm;
91 (void) rdc();
92 unreadc();
93 do {
94 *comptr++ = readchar();
95 } while (check-- && lastc != '\n');
96 *comptr = 0;
97 unreadc();
98 if (check == 0)
99 error(SZBKPT);
100 return;
101
102 case 'k':
103 case 'K':
104 /* kill process */
105 if (pid == 0)
106 error(NOPCS);
107 adbprintf("%d: killed", pid);
108 endpcs();
109 return;
110
111 case 'r':
112 case 'R':
113 /* run program */
114 endpcs();
115 setup();
116 runcount = ecount;
117 runmode = CONTINUOUS;
118 execsig = 0;
119 /* if starting at a breakpoint, run over it */
120 if (scanbkpt(gavedot ? dot : entrypc()) != NULL)
121 runcount++;
122 break;
123
124 case 's':
125 case 'S':
126 /* single step, with optional signal */
127 runcount = ecount;
128 if (pid) {
129 runmode = SINGLESTEP;
130 execsig = oexpr() ? expv : signo;
131 } else {
132 setup();
133 runmode = SINGLESTEP;
134 execsig = 0;
135 runcount--;
136 }
137 break;
138
139 case 'c':
140 case 'C':
141 case 0:
142 /* continue with optional signal */
143 runcount = ecount;
144 if (pid == 0)
145 error(NOPCS);
146 runmode = CONTINUOUS;
147 execsig = oexpr() ? expv : signo;
148 break;
149
150 default:
151 error(BADMOD);
152 /* NOTREACHED */
153 }
154
155 if (runcount > 0 && runpcs(runmode, execsig))
156 adbprintf("breakpoint%16t");
157 else
158 adbprintf("stopped at%16t");
159 delbp();
160 printpc();
161 }
162
163 /*
164 * Print all breakpoints.
165 */
printbkpts()166 printbkpts()
167 {
168 register struct bkpt *b;
169
170 adbprintf("breakpoints\ncount%8tbkpt%24tcommand\n");
171 for (b = bkpthead; b != NULL; b = b->next) {
172 if (b->state != BKPT_FREE) {
173 adbprintf("%-8.8D", b->count);
174 psymoff("%R", b->loc, SP_INSTR, maxoff, "%24t");
175 prints(b->comm);
176 }
177 }
178 }
179
180 /*
181 * Remove (restore to original instruction(s)) all breakpoints.
182 */
delbp()183 delbp()
184 {
185 register struct bkpt *b;
186
187 if (bpstate != BPOUT) {
188 for (b = bkpthead; b != NULL; b = b->next)
189 if (b->state != BKPT_FREE && clr_bpt(b))
190 bperr(b, "clear");
191 bpstate = BPOUT;
192 }
193 }
194
195 /*
196 * Insert all breakpoints.
197 */
setbp()198 setbp()
199 {
200 register struct bkpt *b;
201
202 if (bpstate != BPIN) {
203 for (b = bkpthead; b != NULL; b = b->next)
204 if (b->state != BKPT_FREE && set_bpt(b))
205 bperr(b, "set");
206 bpstate = BPIN;
207 }
208 }
209
210 static
211 bperr(b, how)
212 struct bkpt *b;
213 char *how;
214 {
215
216 adbprintf("cannot %s breakpoint: ", how);
217 psymoff("%R", b->loc, SP_INSTR, maxoff, "\n");
218 }
219
220 /*
221 * Run subprocess for a while.
222 * Return true iff stopped due to breakpoint.
223 */
224 int
runpcs(runmode,execsig)225 runpcs(runmode, execsig)
226 int runmode, execsig;
227 {
228 register struct bkpt *bkpt;
229 int rc;
230
231 /* always set pc, so that expr>pc works too */
232 setpc(gavedot ? dot : getpc());
233 adbprintf("%s: running\n", symfile.name);
234 while (--runcount >= 0) {
235 /* BEGIN XXX (machine dependent?, delete ptrace, etc) */
236 if (runmode == SINGLESTEP)
237 delbp(); /* hardware handles single-stepping */
238 else { /* continuing from a breakpoint is hard */
239 if ((bkpt = scanbkpt(getpc())) != NULL) {
240 execbkpt(bkpt, execsig);
241 execsig = 0;
242 }
243 setbp();
244 }
245 (void) ptrace(runmode == CONTINUOUS ? PT_CONTINUE : PT_STEP,
246 pid, (int *)getpc(), execsig);
247 /* END XXX */
248
249 /* paranoia, SP_DATA usually sufficient, but this is easy */
250 cacheinval(SP_INSTR | SP_DATA);
251
252 bpwait();
253 checkerr();
254 execsig = 0;
255 delbp();
256 readregs();
257
258 if (signo != 0 || (bkpt = scanbkpt(getpc())) == NULL) {
259 execsig = signo;
260 rc = 0;
261 continue;
262 }
263 /* stopped by BPT instruction */
264 #ifdef DEBUG
265 adbprintf("\n BPT code: comm=%s%8tstate=%d",
266 bkpt->comm, bkpt->state);
267 #endif
268 dot = bkpt->loc;
269 switch (bkpt->state) {
270 char *p;
271
272 case BKPT_SET:
273 bkpt->state = BKPT_TRIPPED;
274 if (*bkpt->comm == '\n')
275 break;
276 p = lp;
277 command(bkpt->comm, ':');
278 lp = p;
279 if (gavedot && edot == 0) /* maybe dot==0 ??? */
280 break;
281 if (--bkpt->count == 0)
282 break;
283 /* FALLTHROUGH */
284
285 case BKPT_TRIPPED:
286 execbkpt(bkpt, execsig);
287 execsig = 0;
288 runcount++;
289 continue;
290
291 default:
292 panic("runpcs");
293 /* NOTREACHED */
294 }
295 bkpt->count = bkpt->initcnt;
296 rc = 1;
297 }
298 return (rc);
299 }
300
endpcs()301 endpcs()
302 {
303 register struct bkpt *bp;
304
305 if (pid) {
306 (void) ptrace(PT_KILL, pid, (int *)0, 0); /* XXX */
307 pid = 0;
308 for (bp = bkpthead; bp != NULL; bp = bp->next)
309 if (bp->state != BKPT_FREE)
310 bp->state = BKPT_SET;
311 }
312 bpstate = BPOUT;
313 }
314
315 #ifdef VFORK
nullsig()316 nullsig()
317 {
318
319 }
320 #endif
321
setup()322 setup()
323 {
324
325 cacheinval(SP_INSTR | SP_DATA); /* paranoia */
326 (void) close(symfile.fd);
327 symfile.fd = -1;
328 #ifndef VFORK
329 #define vfork fork
330 #endif
331 if ((pid = vfork()) == 0) {
332 (void) ptrace(PT_TRACE_ME, 0, (int *)0, 0); /* XXX */
333 #ifdef VFORK
334 (void) signal(SIGTRAP, nullsig);
335 #endif
336 (void) signal(SIGINT, sigint);
337 (void) signal(SIGQUIT, sigquit);
338 doexec();
339 exit(0);
340 } else if (pid == -1) {
341 pid = 0;
342 error(NOFORK);
343 } else {
344 bpwait();
345 readregs();
346 symfile.fd = open(symfile.name, wtflag);
347 if (errflag) {
348 adbprintf("%s: cannot execute\n", symfile.name);
349 endpcs();
350 error((char *)0);
351 }
352 }
353 bpstate = BPOUT;
354 }
355
356 /*
357 * Single step over a location containing a breakpoint.
358 */
359 execbkpt(bp, execsig)
360 struct bkpt *bp;
361 int execsig;
362 {
363
364 #ifdef DEBUG
365 adbprintf("exbkpt: %d\n", bp->count);
366 #endif
367 delbp();
368 (void) ptrace(PT_STEP, pid, (int *)bp->loc, execsig); /* XXX */
369 bp->state = BKPT_SET;
370 bpwait();
371 checkerr();
372 readregs();
373 }
374
375 static char separators[] = "<> \t\n";
376
doexec()377 doexec()
378 {
379 register char *p, **ap;
380 register int c;
381 char *argl[LINELEN / 2 + 1];
382 char args[LINELEN];
383 extern char **environ;
384 char *index();
385
386 ap = argl;
387 p = args;
388 *ap++ = symfile.name;
389 do {
390 switch (c = rdc()) {
391
392 case '\n':
393 break;
394
395 case '<':
396 setfile(0, O_RDONLY, 0, p, "open");
397 break;
398
399 case '>':
400 setfile(1, O_CREAT|O_WRONLY, 0666, p, "create");
401 break;
402
403 default:
404 *ap = p;
405 while (index(separators, c) == NULL) {
406 *p++ = c;
407 c = readchar();
408 }
409 *p++ = '\0';
410 ap++;
411 }
412 } while (c != '\n');
413 unreadc();
414 *ap++ = 0;
415 execve(symfile.name, argl, environ);
416 perror(symfile.name);
417 }
418
419 static int
setfile(fd,flags,mode,namebuf,err)420 setfile(fd, flags, mode, namebuf, err)
421 int fd, flags, mode;
422 char *namebuf, *err;
423 {
424 register char *p = namebuf;
425 register int c = rdc();
426
427 while (index(separators, c) == NULL) {
428 *p++ = c;
429 c = readchar();
430 }
431 *p = 0;
432 (void) close(fd);
433 if (open(namebuf, flags, mode) < 0) {
434 adbprintf("%s: cannot %s\n", namebuf, err);
435 _exit(0);
436 /* NOTREACHED */
437 }
438 }
439
440 struct bkpt *
scanbkpt(a)441 scanbkpt(a)
442 register addr_t a;
443 {
444 register struct bkpt *bp;
445
446 for (bp = bkpthead; bp != NULL; bp = bp->next)
447 if (bp->state != BKPT_FREE && bp->loc == a)
448 break;
449 return (bp);
450 }
451
bpwait()452 bpwait()
453 {
454 register int w;
455 union wait status;
456
457 (void) signal(SIGINT, SIG_IGN);
458 while ((w = wait(&status)) != pid && w != -1)
459 /* void */ ;
460 (void) signal(SIGINT, intcatch);
461 if (w == -1) {
462 pid = 0;
463 errflag = BADWAIT;
464 } else if (!WIFSTOPPED(status)) {
465 sigcode = 0;
466 if ((signo = status.w_termsig) != 0)
467 sigprint();
468 if (status.w_coredump) {
469 prints(" - core dumped");
470 (void) close(corefile.fd);
471 setcore();
472 }
473 pid = 0;
474 bpstate = BPOUT;
475 errflag = ENDPCS;
476 } else {
477 signo = status.w_stopsig;
478 sigcode = ptrace(PT_READ_U, pid,
479 &((struct user *)0)->u_code, 0); /* XXX */
480 if (signo != SIGTRAP)
481 sigprint();
482 else
483 signo = 0;
484 flushbuf();
485 }
486 }
487