1 #ifndef lint 2 static char sccsid[] = "@(#)pcs.c 5.1 (Berkeley) 01/16/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 #define NEW 2 /* starting new process, no pc to set */ 38 39 /* sub process control */ 40 41 subpcs(modif) 42 int modif; 43 { 44 register int check; 45 int execsig = 0, runmode; 46 register struct bkpt *bp; 47 char *comptr; 48 49 switch (modif) { 50 51 case 'd': 52 /* delete breakpoint */ 53 if ((bp = scanbkpt(dot)) == NULL) 54 error(NOBKPT); 55 bp->state = BKPT_FREE; 56 return; 57 58 case 'D': 59 /* delete all breapoints */ 60 for (bp = bkpthead; bp != NULL; bp = bp->next) 61 bp->state = BKPT_FREE; 62 return; 63 64 case 'b': 65 case 'B': 66 /* set breakpoint */ 67 if ((bp = scanbkpt(dot)) != NULL) 68 bp->state = BKPT_FREE; 69 else { 70 for (bp = bkpthead; bp != NULL; bp = bp->next) 71 if (bp->state == BKPT_FREE) 72 break; 73 if (bp == NULL) { 74 bp = (struct bkpt *)malloc(sizeof *bp); 75 if (bp == NULL) 76 error(EXBKPT); 77 bp->next = bkpthead; 78 bkpthead = bp; 79 } 80 } 81 bp->loc = dot; 82 bp->initcnt = bp->count = ecount; 83 bp->state = BKPT_SET; 84 check = MAX_BKPTCOM - 1; 85 comptr = bp->comm; 86 (void) rdc(); 87 unreadc(); 88 do { 89 *comptr++ = readchar(); 90 } while (check-- && lastc != '\n'); 91 *comptr = 0; 92 unreadc(); 93 if (check == 0) 94 error(SZBKPT); 95 return; 96 97 case 'k': 98 case 'K': 99 /* kill process */ 100 if (pid == 0) 101 error(NOPCS); 102 adbprintf("%d: killed", pid); 103 endpcs(); 104 return; 105 106 case 'r': 107 case 'R': 108 /* run program */ 109 endpcs(); 110 setup(); 111 runcount = ecount; 112 runmode = CONTINUOUS | NEW; 113 execsig = 0; 114 if (gavedot) { 115 if (scanbkpt(dot) == NULL) 116 runcount++; 117 } else { 118 if (scanbkpt(entrypc()) == NULL) 119 runcount++; 120 } 121 break; 122 123 case 's': 124 case 'S': 125 /* single step, with optional signal */ 126 runcount = ecount; 127 if (pid) { 128 runmode = SINGLESTEP; 129 execsig = oexpr() ? expv : signo; 130 } else { 131 setup(); 132 runmode = SINGLESTEP | NEW; 133 runcount--; 134 execsig = 0; 135 } 136 break; 137 138 case 'c': 139 case 'C': 140 case 0: 141 /* continue with optional signal */ 142 runcount = ecount; 143 if (pid == 0) 144 error(NOPCS); 145 runmode = CONTINUOUS; 146 execsig = oexpr() ? expv : signo; 147 break; 148 149 default: 150 error(BADMOD); 151 } 152 153 if (runcount > 0 && runpcs(runmode & ~NEW, execsig, runmode & NEW)) 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, newproc) 223 int runmode, execsig, newproc; 224 { 225 register struct bkpt *bkpt; 226 int rc; 227 228 /* always set pc, so that expr>pc works too */ 229 setpc(gavedot ? dot : newproc ? entrypc() : getpc()); 230 adbprintf("%s: running\n", symfile.name); 231 while (--runcount >= 0) { 232 #ifdef DEBUG 233 adbprintf("\n%s @ %X sig %D\n", 234 newproc ? "start" : "continue", 235 getpc(), execsig); /* XXX */ 236 #endif 237 /* BEGIN XXX (machine dependent?, delete ptrace, etc) */ 238 if (runmode == SINGLESTEP) 239 delbp(); /* hardware handles single-stepping */ 240 else { /* continuing from a breakpoint is hard */ 241 if (!newproc && (bkpt = scanbkpt(getpc())) != NULL) { 242 execbkpt(bkpt, execsig); 243 execsig = 0; 244 } 245 setbp(); 246 } 247 (void) ptrace(runmode == CONTINUOUS ? PT_CONTINUE : PT_STEP, 248 pid, (int *)(newproc ? 1 : getpc()), execsig); 249 /* END XXX */ 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 (void) close(symfile.fd); 324 symfile.fd = -1; 325 #ifndef VFORK 326 #define vfork fork 327 #endif 328 if ((pid = vfork()) == 0) { 329 (void) ptrace(PT_TRACE_ME, 0, (int *)0, 0); /* XXX */ 330 #ifdef VFORK 331 (void) signal(SIGTRAP, nullsig); 332 #endif 333 (void) signal(SIGINT, sigint); 334 (void) signal(SIGQUIT, sigquit); 335 doexec(); 336 exit(0); 337 } else if (pid == -1) 338 error(NOFORK); 339 else { 340 bpwait(); 341 readregs(); 342 symfile.fd = open(symfile.name, wtflag); 343 if (errflag) { 344 adbprintf("%s: cannot execute\n", symfile.name); 345 endpcs(); 346 error((char *)0); 347 } 348 } 349 bpstate = BPOUT; 350 } 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 exect(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