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