1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)process.c 1.17 (Berkeley) 03/01/85"; 4 5 static char rcsid[] = "$Header: process.c,v 1.5 84/12/26 10:41:37 linton Exp $"; 6 7 /* 8 * Process management. 9 * 10 * This module contains the routines to manage the execution and 11 * tracing of the debuggee process. 12 */ 13 14 #include "defs.h" 15 #include "process.h" 16 #include "machine.h" 17 #include "events.h" 18 #include "tree.h" 19 #include "eval.h" 20 #include "operators.h" 21 #include "source.h" 22 #include "object.h" 23 #include "mappings.h" 24 #include "main.h" 25 #include "coredump.h" 26 #include <signal.h> 27 #include <errno.h> 28 #include <sys/param.h> 29 #include <sys/dir.h> 30 #include <sys/user.h> 31 #include <machine/reg.h> 32 #include <sys/stat.h> 33 34 #ifndef public 35 36 typedef struct Process *Process; 37 38 Process process; 39 40 #define DEFSIG -1 41 42 #include "machine.h" 43 44 #endif 45 46 #define NOTSTARTED 1 47 #define STOPPED 0177 48 #define FINISHED 0 49 50 /* 51 * A cache of the instruction segment is kept to reduce the number 52 * of system calls. Might be better just to read the entire 53 * code space into memory. 54 */ 55 56 #define CSIZE 1003 /* size of instruction cache */ 57 58 typedef struct { 59 Word addr; 60 Word val; 61 } CacheWord; 62 63 /* 64 * This structure holds the information we need from the user structure. 65 */ 66 67 struct Process { 68 int pid; /* process being traced */ 69 int mask; /* process status word */ 70 Word reg[NREG]; /* process' registers */ 71 Word oreg[NREG]; /* registers when process last stopped */ 72 short status; /* either STOPPED or FINISHED */ 73 short signo; /* signal that stopped process */ 74 short sigcode; /* extra signal information */ 75 int exitval; /* return value from exit() */ 76 long sigset; /* bit array of traced signals */ 77 CacheWord word[CSIZE]; /* text segment cache */ 78 Ttyinfo ttyinfo; /* process' terminal characteristics */ 79 Address sigstatus; /* process' handler for current signal */ 80 }; 81 82 /* 83 * These definitions are for the arguments to "pio". 84 */ 85 86 typedef enum { PREAD, PWRITE } PioOp; 87 typedef enum { TEXTSEG, DATASEG } PioSeg; 88 89 private struct Process pbuf; 90 91 #define MAXNCMDARGS 1000 /* maximum number of arguments to RUN */ 92 93 extern int errno; 94 95 private Boolean just_started; 96 private int argc; 97 private String argv[MAXNCMDARGS]; 98 private String infile, outfile; 99 100 /* 101 * Initialize process information. 102 */ 103 104 public process_init() 105 { 106 register Integer i; 107 Char buf[10]; 108 109 process = &pbuf; 110 process->status = (coredump) ? STOPPED : NOTSTARTED; 111 setsigtrace(); 112 for (i = 0; i < NREG; i++) { 113 sprintf(buf, "$r%d", i); 114 defregname(identname(buf, false), i); 115 } 116 defregname(identname("$ap", true), ARGP); 117 defregname(identname("$fp", true), FRP); 118 defregname(identname("$sp", true), STKP); 119 defregname(identname("$pc", true), PROGCTR); 120 if (coredump) { 121 coredump_readin(process->mask, process->reg, process->signo); 122 pc = process->reg[PROGCTR]; 123 getsrcpos(); 124 } 125 arginit(); 126 } 127 128 /* 129 * Routines to get at process information from outside this module. 130 */ 131 132 public Word reg(n) 133 Integer n; 134 { 135 register Word w; 136 137 if (n == NREG) { 138 w = process->mask; 139 } else { 140 w = process->reg[n]; 141 } 142 return w; 143 } 144 145 public setreg(n, w) 146 Integer n; 147 Word w; 148 { 149 process->reg[n] = w; 150 } 151 152 /* 153 * Begin execution. 154 * 155 * We set a breakpoint at the end of the code so that the 156 * process data doesn't disappear after the program terminates. 157 */ 158 159 private Boolean remade(); 160 161 public start(argv, infile, outfile) 162 String argv[]; 163 String infile, outfile; 164 { 165 String pargv[4]; 166 Node cond; 167 168 if (coredump) { 169 coredump = false; 170 fclose(corefile); 171 coredump_close(); 172 } 173 if (argv == nil) { 174 argv = pargv; 175 pargv[0] = objname; 176 pargv[1] = nil; 177 } else { 178 argv[argc] = nil; 179 } 180 pstart(process, argv, infile, outfile); 181 if (remade(objname)) { 182 reinit(argv, infile, outfile); 183 } 184 if (process->status == STOPPED) { 185 pc = 0; 186 setcurfunc(program); 187 if (objsize != 0) { 188 cond = build(O_EQ, build(O_SYM, pcsym), build(O_LCON, lastaddr())); 189 event_once(cond, buildcmdlist(build(O_ENDX))); 190 } 191 } 192 } 193 194 /* 195 * Check to see if the object file has changed since the symbolic 196 * information last was read. 197 */ 198 199 private time_t modtime; 200 201 private Boolean remade(filename) 202 String filename; 203 { 204 struct stat s; 205 Boolean b; 206 207 stat(filename, &s); 208 b = (Boolean) (modtime != 0 and modtime < s.st_mtime); 209 modtime = s.st_mtime; 210 return b; 211 } 212 213 /* 214 * Set up what signals we want to trace. 215 */ 216 217 private setsigtrace() 218 { 219 register Integer i; 220 register Process p; 221 222 p = process; 223 for (i = 1; i <= NSIG; i++) { 224 psigtrace(p, i, true); 225 } 226 psigtrace(p, SIGHUP, false); 227 psigtrace(p, SIGKILL, false); 228 psigtrace(p, SIGALRM, false); 229 psigtrace(p, SIGTSTP, false); 230 psigtrace(p, SIGCONT, false); 231 psigtrace(p, SIGCHLD, false); 232 } 233 234 /* 235 * Initialize the argument list. 236 */ 237 238 public arginit() 239 { 240 infile = nil; 241 outfile = nil; 242 argv[0] = objname; 243 argc = 1; 244 } 245 246 /* 247 * Add an argument to the list for the debuggee. 248 */ 249 250 public newarg(arg) 251 String arg; 252 { 253 if (argc >= MAXNCMDARGS) { 254 error("too many arguments"); 255 } 256 argv[argc++] = arg; 257 } 258 259 /* 260 * Set the standard input for the debuggee. 261 */ 262 263 public inarg(filename) 264 String filename; 265 { 266 if (infile != nil) { 267 error("multiple input redirects"); 268 } 269 infile = filename; 270 } 271 272 /* 273 * Set the standard output for the debuggee. 274 * Probably should check to avoid overwriting an existing file. 275 */ 276 277 public outarg(filename) 278 String filename; 279 { 280 if (outfile != nil) { 281 error("multiple output redirect"); 282 } 283 outfile = filename; 284 } 285 286 /* 287 * Start debuggee executing. 288 */ 289 290 public run() 291 { 292 process->status = STOPPED; 293 fixbps(); 294 curline = 0; 295 start(argv, infile, outfile); 296 just_started = true; 297 isstopped = false; 298 cont(0); 299 } 300 301 /* 302 * Continue execution wherever we left off. 303 * 304 * Note that this routine never returns. Eventually bpact() will fail 305 * and we'll call printstatus or step will call it. 306 */ 307 308 typedef int Intfunc(); 309 310 private Intfunc *dbintr; 311 private intr(); 312 313 public cont(signo) 314 integer signo; 315 { 316 integer s; 317 318 dbintr = signal(SIGINT, intr); 319 if (just_started) { 320 just_started = false; 321 } else { 322 if (not isstopped) { 323 error("can't continue execution"); 324 } 325 isstopped = false; 326 stepover(); 327 } 328 s = signo; 329 for (;;) { 330 if (single_stepping) { 331 printnews(); 332 } else { 333 setallbps(); 334 resume(s); 335 unsetallbps(); 336 s = DEFSIG; 337 if (not isbperr() or not bpact()) { 338 printstatus(); 339 } 340 } 341 stepover(); 342 } 343 /* NOTREACHED */ 344 } 345 346 /* 347 * This routine is called if we get an interrupt while "running" 348 * but actually in the debugger. Could happen, for example, while 349 * processing breakpoints. 350 * 351 * We basically just want to keep going; the assumption is 352 * that when the process resumes it will get the interrupt, 353 * which will then be handled. 354 */ 355 356 private intr() 357 { 358 signal(SIGINT, intr); 359 } 360 361 public fixintr() 362 { 363 signal(SIGINT, dbintr); 364 } 365 366 /* 367 * Resume execution. 368 */ 369 370 public resume(signo) 371 int signo; 372 { 373 register Process p; 374 375 p = process; 376 pcont(p, signo); 377 pc = process->reg[PROGCTR]; 378 if (p->status != STOPPED) { 379 if (p->signo != 0) { 380 error("program terminated by signal %d", p->signo); 381 } else if (not runfirst) { 382 if (p->exitval == 0) { 383 error("program exited"); 384 } else { 385 error("program exited with code %d", p->exitval); 386 } 387 } 388 } 389 } 390 391 /* 392 * Continue execution up to the next source line. 393 * 394 * There are two ways to define the next source line depending on what 395 * is desired when a procedure or function call is encountered. Step 396 * stops at the beginning of the procedure or call; next skips over it. 397 */ 398 399 /* 400 * Stepc is what is called when the step command is given. 401 * It has to play with the "isstopped" information. 402 */ 403 404 public stepc() 405 { 406 if (not isstopped) { 407 error("can't continue execution"); 408 } 409 isstopped = false; 410 dostep(false); 411 isstopped = true; 412 } 413 414 public next() 415 { 416 Address oldfrp, newfrp; 417 418 if (not isstopped) { 419 error("can't continue execution"); 420 } 421 isstopped = false; 422 oldfrp = reg(FRP); 423 do { 424 dostep(true); 425 pc = reg(PROGCTR); 426 newfrp = reg(FRP); 427 } while (newfrp < oldfrp and newfrp != 0); 428 isstopped = true; 429 } 430 431 /* 432 * Continue execution until the current function returns, or, 433 * if the given argument is non-nil, until execution returns to 434 * somewhere within the given function. 435 */ 436 437 public rtnfunc (f) 438 Symbol f; 439 { 440 Address addr; 441 Symbol t; 442 443 if (not isstopped) { 444 error("can't continue execution"); 445 } else if (f != nil and not isactive(f)) { 446 error("%s is not active", symname(f)); 447 } else { 448 addr = return_addr(); 449 if (addr == nil) { 450 error("no place to return to"); 451 } else { 452 isstopped = false; 453 contto(addr); 454 if (f != nil) { 455 for (;;) { 456 t = whatblock(pc); 457 addr = return_addr(); 458 if (t == f or addr == nil) break; 459 contto(addr); 460 } 461 } 462 if (not bpact()) { 463 isstopped = true; 464 printstatus(); 465 } 466 } 467 } 468 } 469 470 /* 471 * Single-step over the current machine instruction. 472 * 473 * If we're single-stepping by source line we want to step to the 474 * next source line. Otherwise we're going to continue so there's 475 * no reason to do all the work necessary to single-step to the next 476 * source line. 477 */ 478 479 public stepover() 480 { 481 Boolean b; 482 483 if (traceexec) { 484 printf("!! stepping over 0x%x\n", process->reg[PROGCTR]); 485 } 486 if (single_stepping) { 487 dostep(false); 488 } else { 489 b = inst_tracing; 490 inst_tracing = true; 491 dostep(false); 492 inst_tracing = b; 493 } 494 if (traceexec) { 495 printf("!! stepped over to 0x%x\n", process->reg[PROGCTR]); 496 } 497 } 498 499 /* 500 * Resume execution up to the given address. We can either ignore 501 * breakpoints (stepto) or catch them (contto). 502 */ 503 504 public stepto(addr) 505 Address addr; 506 { 507 xto(addr, false); 508 } 509 510 private contto (addr) 511 Address addr; 512 { 513 xto(addr, true); 514 } 515 516 private xto (addr, catchbps) 517 Address addr; 518 boolean catchbps; 519 { 520 Address curpc; 521 522 if (catchbps) { 523 stepover(); 524 } 525 curpc = process->reg[PROGCTR]; 526 if (addr != curpc) { 527 if (traceexec) { 528 printf("!! stepping from 0x%x to 0x%x\n", curpc, addr); 529 } 530 if (catchbps) { 531 setallbps(); 532 } 533 setbp(addr); 534 resume(DEFSIG); 535 unsetbp(addr); 536 if (catchbps) { 537 unsetallbps(); 538 } 539 if (not isbperr()) { 540 printstatus(); 541 } 542 } 543 } 544 545 /* 546 * Print the status of the process. 547 * This routine does not return. 548 */ 549 550 public printstatus() 551 { 552 int status; 553 554 if (process->status == FINISHED) { 555 exit(0); 556 } else { 557 setcurfunc(whatblock(pc)); 558 getsrcpos(); 559 if (process->signo == SIGINT) { 560 isstopped = true; 561 printerror(); 562 } else if (isbperr() and isstopped) { 563 printf("stopped "); 564 printloc(); 565 putchar('\n'); 566 if (curline > 0) { 567 printlines(curline, curline); 568 } else { 569 printinst(pc, pc); 570 } 571 erecover(); 572 } else { 573 fixintr(); 574 isstopped = true; 575 printerror(); 576 } 577 } 578 } 579 580 /* 581 * Print out the current location in the debuggee. 582 */ 583 584 public printloc() 585 { 586 printf("in "); 587 printname(stdout, curfunc); 588 putchar(' '); 589 if (curline > 0 and not useInstLoc) { 590 printsrcpos(); 591 } else { 592 useInstLoc = false; 593 curline = 0; 594 printf("at 0x%x", pc); 595 } 596 } 597 598 /* 599 * Some functions for testing the state of the process. 600 */ 601 602 public Boolean notstarted(p) 603 Process p; 604 { 605 return (Boolean) (p->status == NOTSTARTED); 606 } 607 608 public Boolean isfinished(p) 609 Process p; 610 { 611 return (Boolean) (p->status == FINISHED); 612 } 613 614 /* 615 * Predicate to test if the reason the process stopped was because 616 * of a breakpoint. If so, as a side effect clear the local copy of 617 * signal handler associated with process. We must do this so as to 618 * not confuse future stepping or continuing by possibly concluding 619 * the process should continue with a SIGTRAP handler. 620 */ 621 622 public boolean isbperr() 623 { 624 Process p; 625 boolean b; 626 627 p = process; 628 if (p->status == STOPPED and p->signo == SIGTRAP) { 629 b = true; 630 p->sigstatus = 0; 631 } else { 632 b = false; 633 } 634 return b; 635 } 636 637 /* 638 * Return the signal number that stopped the process. 639 */ 640 641 public integer errnum (p) 642 Process p; 643 { 644 return p->signo; 645 } 646 647 /* 648 * Return the signal code associated with the signal. 649 */ 650 651 public integer errcode (p) 652 Process p; 653 { 654 return p->sigcode; 655 } 656 657 /* 658 * Return the termination code of the process. 659 */ 660 661 public integer exitcode (p) 662 Process p; 663 { 664 return p->exitval; 665 } 666 667 /* 668 * These routines are used to access the debuggee process from 669 * outside this module. 670 * 671 * They invoke "pio" which eventually leads to a call to "ptrace". 672 * The system generates an I/O error when a ptrace fails. During reads 673 * these are ignored, during writes they are reported as an error, and 674 * for anything else they cause a fatal error. 675 */ 676 677 extern Intfunc *onsyserr(); 678 679 private badaddr; 680 private read_err(), write_err(); 681 682 /* 683 * Read from the process' instruction area. 684 */ 685 686 public iread(buff, addr, nbytes) 687 char *buff; 688 Address addr; 689 int nbytes; 690 { 691 Intfunc *f; 692 693 f = onsyserr(EIO, read_err); 694 badaddr = addr; 695 if (coredump) { 696 coredump_readtext(buff, addr, nbytes); 697 } else { 698 pio(process, PREAD, TEXTSEG, buff, addr, nbytes); 699 } 700 onsyserr(EIO, f); 701 } 702 703 /* 704 * Write to the process' instruction area, usually in order to set 705 * or unset a breakpoint. 706 */ 707 708 public iwrite(buff, addr, nbytes) 709 char *buff; 710 Address addr; 711 int nbytes; 712 { 713 Intfunc *f; 714 715 if (coredump) { 716 error("no process to write to"); 717 } 718 f = onsyserr(EIO, write_err); 719 badaddr = addr; 720 pio(process, PWRITE, TEXTSEG, buff, addr, nbytes); 721 onsyserr(EIO, f); 722 } 723 724 /* 725 * Read for the process' data area. 726 */ 727 728 public dread(buff, addr, nbytes) 729 char *buff; 730 Address addr; 731 int nbytes; 732 { 733 Intfunc *f; 734 735 badaddr = addr; 736 if (coredump) { 737 f = onsyserr(EFAULT, read_err); 738 coredump_readdata(buff, addr, nbytes); 739 onsyserr(EFAULT, f); 740 } else { 741 f = onsyserr(EIO, read_err); 742 pio(process, PREAD, DATASEG, buff, addr, nbytes); 743 onsyserr(EIO, f); 744 } 745 } 746 747 /* 748 * Write to the process' data area. 749 */ 750 751 public dwrite(buff, addr, nbytes) 752 char *buff; 753 Address addr; 754 int nbytes; 755 { 756 Intfunc *f; 757 758 if (coredump) { 759 error("no process to write to"); 760 } 761 f = onsyserr(EIO, write_err); 762 badaddr = addr; 763 pio(process, PWRITE, DATASEG, buff, addr, nbytes); 764 onsyserr(EIO, f); 765 } 766 767 /* 768 * Trap for errors in reading or writing to a process. 769 * The current approach is to "ignore" read errors and complain 770 * bitterly about write errors. 771 */ 772 773 private read_err() 774 { 775 /* 776 * Ignore. 777 */ 778 } 779 780 private write_err() 781 { 782 error("can't write to process (address 0x%x)", badaddr); 783 } 784 785 /* 786 * Ptrace interface. 787 */ 788 789 /* 790 * This magic macro enables us to look at the process' registers 791 * in its user structure. 792 */ 793 794 #define regloc(reg) (ctob(UPAGES) + ( sizeof(int) * (reg) )) 795 796 #define WMASK (~(sizeof(Word) - 1)) 797 #define cachehash(addr) ((unsigned) ((addr >> 2) % CSIZE)) 798 799 #define FIRSTSIG SIGINT 800 #define LASTSIG SIGQUIT 801 #define ischild(pid) ((pid) == 0) 802 #define traceme() ptrace(0, 0, 0, 0) 803 #define setrep(n) (1 << ((n)-1)) 804 #define istraced(p) (p->sigset&setrep(p->signo)) 805 806 /* 807 * Ptrace options (specified in first argument). 808 */ 809 810 #define UREAD 3 /* read from process's user structure */ 811 #define UWRITE 6 /* write to process's user structure */ 812 #define IREAD 1 /* read from process's instruction space */ 813 #define IWRITE 4 /* write to process's instruction space */ 814 #define DREAD 2 /* read from process's data space */ 815 #define DWRITE 5 /* write to process's data space */ 816 #define CONT 7 /* continue stopped process */ 817 #define SSTEP 9 /* continue for approximately one instruction */ 818 #define PKILL 8 /* terminate the process */ 819 820 /* 821 * Start up a new process by forking and exec-ing the 822 * given argument list, returning when the process is loaded 823 * and ready to execute. The PROCESS information (pointed to 824 * by the first argument) is appropriately filled. 825 * 826 * If the given PROCESS structure is associated with an already running 827 * process, we terminate it. 828 */ 829 830 /* VARARGS2 */ 831 private pstart(p, argv, infile, outfile) 832 Process p; 833 String argv[]; 834 String infile; 835 String outfile; 836 { 837 int status; 838 839 if (p->pid != 0) { 840 pterm(p); 841 cacheflush(p); 842 } 843 fflush(stdout); 844 psigtrace(p, SIGTRAP, true); 845 p->pid = vfork(); 846 if (p->pid == -1) { 847 panic("can't fork"); 848 } 849 if (ischild(p->pid)) { 850 nocatcherrs(); 851 traceme(); 852 if (infile != nil) { 853 infrom(infile); 854 } 855 if (outfile != nil) { 856 outto(outfile); 857 } 858 execv(argv[0], argv); 859 _exit(1); 860 } 861 pwait(p->pid, &status); 862 getinfo(p, status); 863 if (p->status != STOPPED) { 864 beginerrmsg(); 865 fprintf(stderr, "warning: cannot execute %s\n", argv[0]); 866 } else { 867 ptraced(p->pid); 868 } 869 } 870 871 /* 872 * Terminate a ptrace'd process. 873 */ 874 875 public pterm (p) 876 Process p; 877 { 878 integer status; 879 880 if (p != nil and p->pid != 0) { 881 ptrace(PKILL, p->pid, 0, 0); 882 pwait(p->pid, &status); 883 unptraced(p->pid); 884 } 885 } 886 887 /* 888 * Continue a stopped process. The first argument points to a Process 889 * structure. Before the process is restarted it's user area is modified 890 * according to the values in the structure. When this routine finishes, 891 * the structure has the new values from the process's user area. 892 * 893 * Pcont terminates when the process stops with a signal pending that 894 * is being traced (via psigtrace), or when the process terminates. 895 */ 896 897 private pcont(p, signo) 898 Process p; 899 int signo; 900 { 901 int s, status; 902 903 if (p->pid == 0) { 904 error("program is not active"); 905 } 906 s = signo; 907 do { 908 setinfo(p, s); 909 if (traceexec) { 910 printf("!! pcont from 0x%x with signal %d (%d)\n", 911 p->reg[PROGCTR], s, p->signo); 912 fflush(stdout); 913 } 914 sigs_off(); 915 if (ptrace(CONT, p->pid, p->reg[PROGCTR], p->signo) < 0) { 916 panic("error %d trying to continue process", errno); 917 } 918 pwait(p->pid, &status); 919 sigs_on(); 920 getinfo(p, status); 921 if (p->status == STOPPED and traceexec and not istraced(p)) { 922 printf("!! ignored signal %d at 0x%x\n", 923 p->signo, p->reg[PROGCTR]); 924 fflush(stdout); 925 } 926 s = p->signo; 927 } while (p->status == STOPPED and not istraced(p)); 928 if (traceexec) { 929 printf("!! pcont to 0x%x on signal %d\n", p->reg[PROGCTR], p->signo); 930 fflush(stdout); 931 } 932 } 933 934 /* 935 * Single step as best ptrace can. 936 */ 937 938 public pstep(p, signo) 939 Process p; 940 integer signo; 941 { 942 int s, status; 943 944 s = signo; 945 do { 946 setinfo(p, s); 947 if (traceexec) { 948 printf("!! pstep from 0x%x with signal %d (%d)\n", 949 p->reg[PROGCTR], s, p->signo); 950 fflush(stdout); 951 } 952 sigs_off(); 953 if (ptrace(SSTEP, p->pid, p->reg[PROGCTR], p->signo) < 0) { 954 panic("error %d trying to step process", errno); 955 } 956 pwait(p->pid, &status); 957 sigs_on(); 958 getinfo(p, status); 959 if (p->status == STOPPED and traceexec and not istraced(p)) { 960 printf("!! pstep ignored signal %d at 0x%x\n", 961 p->signo, p->reg[PROGCTR]); 962 fflush(stdout); 963 } 964 s = p->signo; 965 } while (p->status == STOPPED and not istraced(p)); 966 if (traceexec) { 967 printf("!! pstep to 0x%x on signal %d\n", 968 p->reg[PROGCTR], p->signo); 969 fflush(stdout); 970 } 971 if (p->status != STOPPED) { 972 if (p->exitval == 0) { 973 error("program exited\n"); 974 } else { 975 error("program exited with code %d\n", p->exitval); 976 } 977 } 978 } 979 980 /* 981 * Return from execution when the given signal is pending. 982 */ 983 984 public psigtrace(p, sig, sw) 985 Process p; 986 int sig; 987 Boolean sw; 988 { 989 if (sw) { 990 p->sigset |= setrep(sig); 991 } else { 992 p->sigset &= ~setrep(sig); 993 } 994 } 995 996 /* 997 * Don't catch any signals. 998 * Particularly useful when letting a process finish uninhibited. 999 */ 1000 1001 public unsetsigtraces(p) 1002 Process p; 1003 { 1004 p->sigset = 0; 1005 } 1006 1007 /* 1008 * Turn off attention to signals not being caught. 1009 */ 1010 1011 private Intfunc *sigfunc[NSIG]; 1012 1013 private sigs_off() 1014 { 1015 register int i; 1016 1017 for (i = FIRSTSIG; i < LASTSIG; i++) { 1018 if (i != SIGKILL) { 1019 sigfunc[i] = signal(i, SIG_IGN); 1020 } 1021 } 1022 } 1023 1024 /* 1025 * Turn back on attention to signals. 1026 */ 1027 1028 private sigs_on() 1029 { 1030 register int i; 1031 1032 for (i = FIRSTSIG; i < LASTSIG; i++) { 1033 if (i != SIGKILL) { 1034 signal(i, sigfunc[i]); 1035 } 1036 } 1037 } 1038 1039 /* 1040 * Get process information from user area. 1041 */ 1042 1043 private int rloc[] ={ 1044 R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, AP, FP, SP, PC 1045 }; 1046 1047 private getinfo(p, status) 1048 register Process p; 1049 register int status; 1050 { 1051 register int i; 1052 Address addr; 1053 1054 p->signo = (status&0177); 1055 p->exitval = ((status >> 8)&0377); 1056 if (p->signo != STOPPED) { 1057 p->status = FINISHED; 1058 p->pid = 0; 1059 p->reg[PROGCTR] = 0; 1060 } else { 1061 p->status = p->signo; 1062 p->signo = p->exitval; 1063 p->sigcode = ptrace(UREAD, p->pid, &((struct user *) 0)->u_code, 0); 1064 p->exitval = 0; 1065 p->mask = ptrace(UREAD, p->pid, regloc(PS), 0); 1066 for (i = 0; i < NREG; i++) { 1067 p->reg[i] = ptrace(UREAD, p->pid, regloc(rloc[i]), 0); 1068 p->oreg[i] = p->reg[i]; 1069 } 1070 savetty(stdout, &(p->ttyinfo)); 1071 addr = (Address) &(((struct user *) 0)->u_signal[p->signo]); 1072 p->sigstatus = (Address) ptrace(UREAD, p->pid, addr, 0); 1073 } 1074 } 1075 1076 /* 1077 * Set process's user area information from given process structure. 1078 */ 1079 1080 private setinfo(p, signo) 1081 register Process p; 1082 int signo; 1083 { 1084 register int i; 1085 register int r; 1086 1087 if (signo == DEFSIG) { 1088 if (istraced(p) and (p->sigstatus == 0 or p->sigstatus == 1)) { 1089 p->signo = 0; 1090 } 1091 } else { 1092 p->signo = signo; 1093 } 1094 for (i = 0; i < NREG; i++) { 1095 if ((r = p->reg[i]) != p->oreg[i]) { 1096 ptrace(UWRITE, p->pid, regloc(rloc[i]), r); 1097 } 1098 } 1099 restoretty(stdout, &(p->ttyinfo)); 1100 } 1101 1102 /* 1103 * Return the address associated with the current signal. 1104 * (Plus two since the address points to the beginning of a procedure). 1105 */ 1106 1107 public Address usignal (p) 1108 Process p; 1109 { 1110 Address r; 1111 1112 r = p->sigstatus; 1113 if (r != 0 and r != 1) { 1114 r += 2; 1115 } 1116 return r; 1117 } 1118 1119 /* 1120 * Structure for reading and writing by words, but dealing with bytes. 1121 */ 1122 1123 typedef union { 1124 Word pword; 1125 Byte pbyte[sizeof(Word)]; 1126 } Pword; 1127 1128 /* 1129 * Read (write) from (to) the process' address space. 1130 * We must deal with ptrace's inability to look anywhere other 1131 * than at a word boundary. 1132 */ 1133 1134 private Word fetch(); 1135 private store(); 1136 1137 private pio(p, op, seg, buff, addr, nbytes) 1138 Process p; 1139 PioOp op; 1140 PioSeg seg; 1141 char *buff; 1142 Address addr; 1143 int nbytes; 1144 { 1145 register int i; 1146 register Address newaddr; 1147 register char *cp; 1148 char *bufend; 1149 Pword w; 1150 Address wordaddr; 1151 int byteoff; 1152 1153 if (p->status != STOPPED) { 1154 error("program is not active"); 1155 } 1156 cp = buff; 1157 newaddr = addr; 1158 wordaddr = (newaddr&WMASK); 1159 if (wordaddr != newaddr) { 1160 w.pword = fetch(p, seg, wordaddr); 1161 for (i = newaddr - wordaddr; i < sizeof(Word) and nbytes > 0; i++) { 1162 if (op == PREAD) { 1163 *cp++ = w.pbyte[i]; 1164 } else { 1165 w.pbyte[i] = *cp++; 1166 } 1167 nbytes--; 1168 } 1169 if (op == PWRITE) { 1170 store(p, seg, wordaddr, w.pword); 1171 } 1172 newaddr = wordaddr + sizeof(Word); 1173 } 1174 byteoff = (nbytes&(~WMASK)); 1175 nbytes -= byteoff; 1176 bufend = cp + nbytes; 1177 while (cp < bufend) { 1178 if (op == PREAD) { 1179 *((Word *) cp) = fetch(p, seg, newaddr); 1180 } else { 1181 store(p, seg, newaddr, *((Word *) cp)); 1182 } 1183 cp += sizeof(Word); 1184 newaddr += sizeof(Word); 1185 } 1186 if (byteoff > 0) { 1187 w.pword = fetch(p, seg, newaddr); 1188 for (i = 0; i < byteoff; i++) { 1189 if (op == PREAD) { 1190 *cp++ = w.pbyte[i]; 1191 } else { 1192 w.pbyte[i] = *cp++; 1193 } 1194 } 1195 if (op == PWRITE) { 1196 store(p, seg, newaddr, w.pword); 1197 } 1198 } 1199 } 1200 1201 /* 1202 * Get a word from a process at the given address. 1203 * The address is assumed to be on a word boundary. 1204 * 1205 * A simple cache scheme is used to avoid redundant ptrace calls 1206 * to the instruction space since it is assumed to be pure. 1207 * 1208 * It is necessary to use a write-through scheme so that 1209 * breakpoints right next to each other don't interfere. 1210 */ 1211 1212 private Integer nfetchs, nreads, nwrites; 1213 1214 private Word fetch(p, seg, addr) 1215 Process p; 1216 PioSeg seg; 1217 register int addr; 1218 { 1219 register CacheWord *wp; 1220 register Word w; 1221 1222 switch (seg) { 1223 case TEXTSEG: 1224 ++nfetchs; 1225 wp = &p->word[cachehash(addr)]; 1226 if (addr == 0 or wp->addr != addr) { 1227 ++nreads; 1228 w = ptrace(IREAD, p->pid, addr, 0); 1229 wp->addr = addr; 1230 wp->val = w; 1231 } else { 1232 w = wp->val; 1233 } 1234 break; 1235 1236 case DATASEG: 1237 w = ptrace(DREAD, p->pid, addr, 0); 1238 break; 1239 1240 default: 1241 panic("fetch: bad seg %d", seg); 1242 /* NOTREACHED */ 1243 } 1244 return w; 1245 } 1246 1247 /* 1248 * Put a word into the process' address space at the given address. 1249 * The address is assumed to be on a word boundary. 1250 */ 1251 1252 private store(p, seg, addr, data) 1253 Process p; 1254 PioSeg seg; 1255 int addr; 1256 Word data; 1257 { 1258 register CacheWord *wp; 1259 1260 switch (seg) { 1261 case TEXTSEG: 1262 ++nwrites; 1263 wp = &p->word[cachehash(addr)]; 1264 wp->addr = addr; 1265 wp->val = data; 1266 ptrace(IWRITE, p->pid, addr, data); 1267 break; 1268 1269 case DATASEG: 1270 ptrace(DWRITE, p->pid, addr, data); 1271 break; 1272 1273 default: 1274 panic("store: bad seg %d", seg); 1275 /* NOTREACHED */ 1276 } 1277 } 1278 1279 /* 1280 * Flush the instruction cache associated with a process. 1281 */ 1282 1283 private cacheflush (p) 1284 Process p; 1285 { 1286 bzero(p->word, sizeof(p->word)); 1287 } 1288 1289 public printptraceinfo() 1290 { 1291 printf("%d fetchs, %d reads, %d writes\n", nfetchs, nreads, nwrites); 1292 } 1293 1294 /* 1295 * Redirect input. 1296 * Assuming this is called from a child, we should be careful to avoid 1297 * (possibly) shared standard I/O buffers. 1298 */ 1299 1300 private infrom (filename) 1301 String filename; 1302 { 1303 Fileid in; 1304 1305 in = open(filename, 0); 1306 if (in == -1) { 1307 write(2, "can't read ", 11); 1308 write(2, filename, strlen(filename)); 1309 write(2, "\n", 1); 1310 _exit(1); 1311 } 1312 fswap(0, in); 1313 } 1314 1315 /* 1316 * Redirect standard output. 1317 * Same assumptions as for "infrom" above. 1318 */ 1319 1320 private outto (filename) 1321 String filename; 1322 { 1323 Fileid out; 1324 1325 out = creat(filename, 0666); 1326 if (out == -1) { 1327 write(2, "can't write ", 12); 1328 write(2, filename, strlen(filename)); 1329 write(2, "\n", 1); 1330 _exit(1); 1331 } 1332 fswap(1, out); 1333 } 1334 1335 /* 1336 * Swap file numbers, useful for redirecting standard input or output. 1337 */ 1338 1339 private fswap(oldfd, newfd) 1340 Fileid oldfd; 1341 Fileid newfd; 1342 { 1343 if (oldfd != newfd) { 1344 close(oldfd); 1345 dup(newfd); 1346 close(newfd); 1347 } 1348 } 1349 1350 /* 1351 * Signal name manipulation. 1352 */ 1353 1354 private String signames[NSIG] = { 1355 0, 1356 "HUP", "INT", "QUIT", "ILL", "TRAP", 1357 "IOT", "EMT", "FPE", "KILL", "BUS", 1358 "SEGV", "SYS", "PIPE", "ALRM", "TERM", 1359 0, "STOP", "TSTP", "CONT", "CHLD", 1360 "TTIN", "TTOU", "TINT", "XCPU", "XFSZ", 1361 }; 1362 1363 /* 1364 * Get the signal number associated with a given name. 1365 * The name is first translated to upper case if necessary. 1366 */ 1367 1368 public integer siglookup (s) 1369 String s; 1370 { 1371 register char *p, *q; 1372 char buf[100]; 1373 integer i; 1374 1375 p = s; 1376 q = buf; 1377 while (*p != '\0') { 1378 if (*p >= 'a' and *p <= 'z') { 1379 *q = (*p - 'a') + 'A'; 1380 } else { 1381 *q = *p; 1382 } 1383 ++p; 1384 ++q; 1385 } 1386 *q = '\0'; 1387 p = buf; 1388 if (buf[0] == 'S' and buf[1] == 'I' and buf[2] == 'G') { 1389 p += 3; 1390 } 1391 i = 1; 1392 for (;;) { 1393 if (i >= sizeof(signames) div sizeof(signames[0])) { 1394 error("signal \"%s\" unknown", s); 1395 i = 0; 1396 break; 1397 } 1398 if (signames[i] != nil and streq(signames[i], p)) { 1399 break; 1400 } 1401 ++i; 1402 } 1403 return i; 1404 } 1405 1406 /* 1407 * Print all signals being ignored by the debugger. 1408 * These signals are auotmatically 1409 * passed on to the debugged process. 1410 */ 1411 1412 public printsigsignored (p) 1413 Process p; 1414 { 1415 printsigs(~p->sigset); 1416 } 1417 1418 /* 1419 * Print all signals being intercepted by 1420 * the debugger for the specified process. 1421 */ 1422 1423 public printsigscaught(p) 1424 Process p; 1425 { 1426 printsigs(p->sigset); 1427 } 1428 1429 private printsigs (set) 1430 integer set; 1431 { 1432 integer s; 1433 char separator[2]; 1434 1435 separator[0] = '\0'; 1436 for (s = 1; s < sizeof(signames) div sizeof(signames[0]); s++) { 1437 if (set & setrep(s)) { 1438 if (signames[s] != nil) { 1439 printf("%s%s", separator, signames[s]); 1440 separator[0] = ' '; 1441 separator[1] = '\0'; 1442 } 1443 } 1444 } 1445 if (separator[0] == ' ') { 1446 putchar('\n'); 1447 } 1448 } 1449