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