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