1 #ifndef lint 2 static char sccsid[] = "@(#)pcs.c 5.3 (Berkeley) 01/17/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 * ... return true iff stopped due to breakpoint 220 */ 221 int 222 runpcs(runmode, execsig) 223 int runmode, execsig; 224 { 225 register struct bkpt *bkpt; 226 int rc; 227 228 /* always set pc, so that expr>pc works too */ 229 setpc(gavedot ? dot : getpc()); 230 adbprintf("%s: running\n", symfile.name); 231 while (--runcount >= 0) { 232 /* BEGIN XXX (machine dependent?, delete ptrace, etc) */ 233 if (runmode == SINGLESTEP) 234 delbp(); /* hardware handles single-stepping */ 235 else { /* continuing from a breakpoint is hard */ 236 if ((bkpt = scanbkpt(getpc())) != NULL) { 237 execbkpt(bkpt, execsig); 238 execsig = 0; 239 } 240 setbp(); 241 } 242 (void) ptrace(runmode == CONTINUOUS ? PT_CONTINUE : PT_STEP, 243 pid, (int *)getpc(), execsig); 244 /* END XXX */ 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 (void) close(symfile.fd); 319 symfile.fd = -1; 320 #ifndef VFORK 321 #define vfork fork 322 #endif 323 if ((pid = vfork()) == 0) { 324 (void) ptrace(PT_TRACE_ME, 0, (int *)0, 0); /* XXX */ 325 #ifdef VFORK 326 (void) signal(SIGTRAP, nullsig); 327 #endif 328 (void) signal(SIGINT, sigint); 329 (void) signal(SIGQUIT, sigquit); 330 doexec(); 331 exit(0); 332 } else if (pid == -1) 333 error(NOFORK); 334 else { 335 bpwait(); 336 readregs(); 337 symfile.fd = open(symfile.name, wtflag); 338 if (errflag) { 339 adbprintf("%s: cannot execute\n", symfile.name); 340 endpcs(); 341 error((char *)0); 342 } 343 } 344 bpstate = BPOUT; 345 } 346 347 execbkpt(bp, execsig) 348 struct bkpt *bp; 349 int execsig; 350 { 351 352 #ifdef DEBUG 353 adbprintf("exbkpt: %d\n", bp->count); 354 #endif 355 delbp(); 356 (void) ptrace(PT_STEP, pid, (int *)bp->loc, execsig); /* XXX */ 357 bp->state = BKPT_SET; 358 bpwait(); 359 checkerr(); 360 readregs(); 361 } 362 363 static char separators[] = "<> \t\n"; 364 365 doexec() 366 { 367 register char *p, **ap; 368 register int c; 369 char *argl[LINELEN / 2 + 1]; 370 char args[LINELEN]; 371 extern char **environ; 372 char *index(); 373 374 ap = argl; 375 p = args; 376 *ap++ = symfile.name; 377 do { 378 switch (c = rdc()) { 379 380 case '\n': 381 break; 382 383 case '<': 384 setfile(0, O_RDONLY, 0, p, "open"); 385 break; 386 387 case '>': 388 setfile(1, O_CREAT|O_WRONLY, 0666, p, "create"); 389 break; 390 391 default: 392 *ap = p; 393 while (index(separators, c) == NULL) { 394 *p++ = c; 395 c = readchar(); 396 } 397 *p++ = '\0'; 398 ap++; 399 } 400 } while (c != '\n'); 401 unreadc(); 402 *ap++ = 0; 403 execve(symfile.name, argl, environ); 404 perror(symfile.name); 405 } 406 407 static int 408 setfile(fd, flags, mode, namebuf, err) 409 int fd, flags, mode; 410 char *namebuf, *err; 411 { 412 register char *p = namebuf; 413 register int c = rdc(); 414 415 while (index(separators, c) == NULL) { 416 *p++ = c; 417 c = readchar(); 418 } 419 *p = 0; 420 (void) close(fd); 421 if (open(namebuf, flags, mode) < 0) { 422 adbprintf("%s: cannot %s\n", namebuf, err); 423 _exit(0); 424 /* NOTREACHED */ 425 } 426 } 427 428 struct bkpt * 429 scanbkpt(a) 430 register addr_t a; 431 { 432 register struct bkpt *bp; 433 434 for (bp = bkpthead; bp != NULL; bp = bp->next) 435 if (bp->state != BKPT_FREE && bp->loc == a) 436 break; 437 return (bp); 438 } 439 440 bpwait() 441 { 442 register int w; 443 union wait status; 444 445 (void) signal(SIGINT, SIG_IGN); 446 while ((w = wait(&status)) != pid && w != -1) 447 /* void */ ; 448 (void) signal(SIGINT, intcatch); 449 if (w == -1) { 450 pid = 0; 451 errflag = BADWAIT; 452 } else if (!WIFSTOPPED(status)) { 453 sigcode = 0; 454 if ((signo = status.w_termsig) != 0) 455 sigprint(); 456 if (status.w_coredump) { 457 prints(" - core dumped"); 458 (void) close(corefile.fd); 459 setcore(); 460 } 461 pid = 0; 462 bpstate = BPOUT; 463 errflag = ENDPCS; 464 } else { 465 signo = status.w_stopsig; 466 sigcode = ptrace(PT_READ_U, pid, 467 &((struct user *)0)->u_code, 0); /* XXX */ 468 if (signo != SIGTRAP) 469 sigprint(); 470 else 471 signo = 0; 472 flushbuf(); 473 } 474 } 475