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