1 2 /* Copyright (c) 1982 Regents of the University of California */ 3 4 static char sccsid[] = "@(#)ptrace.c 1.4 12/29/82"; 5 6 /* 7 * routines for tracing the execution of a process 8 * 9 * The system call "ptrace" does all the work, these 10 * routines just try to interface easily to it. 11 */ 12 13 #include "defs.h" 14 #include <signal.h> 15 #include <sys/param.h> 16 #include <machine/reg.h> 17 #include "process.h" 18 #include "object.h" 19 #include "process.rep" 20 21 # if (isvaxpx) 22 # include "pxinfo.h" 23 # endif 24 25 #ifndef vax 26 # define U_PAGE 0x2400 27 # define U_AR0 (14*sizeof(int)) 28 LOCAL int ar0val = -1; 29 #endif 30 31 /* 32 * This magic macro enables us to look at the process' registers 33 * in its user structure. Very gross. 34 */ 35 36 #ifdef vax 37 # define regloc(reg) (ctob(UPAGES) + ( sizeof(int) * (reg) )) 38 #else 39 # define regloc(reg) (ar0val + ( sizeof(int) * (reg) )) 40 #endif 41 42 #define WMASK (~(sizeof(WORD) - 1)) 43 #define cachehash(addr) ((unsigned) ((addr >> 2) % CSIZE)) 44 45 #define FIRSTSIG SIGINT 46 #define LASTSIG SIGQUIT 47 #define ischild(pid) ((pid) == 0) 48 #define traceme() ptrace(0, 0, 0, 0) 49 #define setrep(n) (1 << ((n)-1)) 50 #define istraced(p) (p->sigset&setrep(p->signo)) 51 52 /* 53 * ptrace options (specified in first argument) 54 */ 55 56 #define UREAD 3 /* read from process's user structure */ 57 #define UWRITE 6 /* write to process's user structure */ 58 #define IREAD 1 /* read from process's instruction space */ 59 #define IWRITE 4 /* write to process's instruction space */ 60 #define DREAD 2 /* read from process's data space */ 61 #define DWRITE 5 /* write to process's data space */ 62 #define CONT 7 /* continue stopped process */ 63 #define SSTEP 9 /* continue for approximately one instruction */ 64 #define PKILL 8 /* terminate the process */ 65 66 /* 67 * Start up a new process by forking and exec-ing the 68 * given argument list, returning when the process is loaded 69 * and ready to execute. The PROCESS information (pointed to 70 * by the first argument) is appropriately filled. 71 * 72 * If the given PROCESS structure is associated with an already running 73 * process, we terminate it. 74 */ 75 76 /* VARARGS2 */ 77 pstart(p, cmd, argv, infile, outfile) 78 PROCESS *p; 79 char *cmd; 80 char **argv; 81 char *infile; 82 char *outfile; 83 { 84 int status; 85 FILE *in, *out; 86 87 if (p->pid != 0) { /* child already running? */ 88 ptrace(PKILL, p->pid, 0, 0); /* ... kill it! */ 89 } 90 psigtrace(p, SIGTRAP, TRUE); 91 if ((p->pid = fork()) == -1) { 92 panic("can't fork"); 93 } 94 if (ischild(p->pid)) { 95 traceme(); 96 if (infile != NIL) { 97 if ((in = fopen(infile, "r")) == NIL) { 98 printf("can't read %s\n", infile); 99 exit(1); 100 } 101 fswap(0, fileno(in)); 102 } 103 if (outfile != NIL) { 104 if ((out = fopen(outfile, "w")) == NIL) { 105 printf("can't write %s\n", outfile); 106 exit(1); 107 } 108 fswap(1, fileno(out)); 109 } 110 execvp(cmd, argv); 111 panic("can't exec %s", argv[0]); 112 } 113 pwait(p->pid, &status); 114 getinfo(p, status); 115 } 116 117 /* 118 * Continue a stopped process. The argument points to a PROCESS structure. 119 * Before the process is restarted it's user area is modified according to 120 * the values in the structure. When this routine finishes, 121 * the structure has the new values from the process's user area. 122 * 123 * Pcont terminates when the process stops with a signal pending that 124 * is being traced (via psigtrace), or when the process terminates. 125 */ 126 127 pcont(p) 128 PROCESS *p; 129 { 130 int status; 131 132 if (p->pid == 0) { 133 error("program not active"); 134 } 135 do { 136 setinfo(p); 137 sigs_off(); 138 if (ptrace(CONT, p->pid, p->pc, p->signo) < 0) { 139 panic("can't continue process"); 140 } 141 pwait(p->pid, &status); 142 sigs_on(); 143 getinfo(p, status); 144 } while (p->status == STOPPED && !istraced(p)); 145 } 146 147 /* 148 * single step as best ptrace can 149 */ 150 151 pstep(p) 152 PROCESS *p; 153 { 154 int status; 155 156 setinfo(p); 157 sigs_off(); 158 ptrace(SSTEP, p->pid, p->pc, p->signo); 159 pwait(p->pid, &status); 160 sigs_on(); 161 getinfo(p, status); 162 } 163 164 /* 165 * Return from execution when the given signal is pending. 166 */ 167 168 psigtrace(p, sig, sw) 169 PROCESS *p; 170 int sig; 171 int sw; 172 { 173 if (sw) { 174 p->sigset |= setrep(sig); 175 } else { 176 p->sigset &= ~setrep(sig); 177 } 178 } 179 180 /* 181 * Don't catch any signals. 182 * Particularly useful when letting a process finish uninhibited (i.e. px). 183 */ 184 185 unsetsigtraces(p) 186 PROCESS *p; 187 { 188 p->sigset = 0; 189 } 190 191 /* 192 * turn off attention to signals not being caught 193 */ 194 195 typedef int INTFUNC(); 196 197 LOCAL INTFUNC *sigfunc[NSIG]; 198 199 LOCAL sigs_off() 200 { 201 register int i; 202 203 for (i = FIRSTSIG; i < LASTSIG; i++) { 204 if (i != SIGKILL) { 205 sigfunc[i] = signal(i, SIG_IGN); 206 } 207 } 208 } 209 210 /* 211 * turn back on attention to signals 212 */ 213 214 LOCAL sigs_on() 215 { 216 register int i; 217 218 for (i = FIRSTSIG; i < LASTSIG; i++) { 219 if (i != SIGKILL) { 220 signal(i, sigfunc[i]); 221 } 222 } 223 } 224 225 /* 226 * get PROCESS information from process's user area 227 */ 228 229 #if vax 230 LOCAL int rloc[] ={ 231 R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, 232 }; 233 #else 234 LOCAL int rloc[] ={ 235 R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5, 236 }; 237 #endif 238 239 LOCAL getinfo(p, status) 240 register PROCESS *p; 241 register int status; 242 { 243 register int i; 244 245 p->signo = (status&0177); 246 p->exitval = ((status >> 8)&0377); 247 if (p->signo == STOPPED) { 248 p->status = p->signo; 249 p->signo = p->exitval; 250 p->exitval = 0; 251 } else { 252 p->status = FINISHED; 253 return; 254 } 255 #ifndef vax 256 if (ar0val < 0){ 257 ar0val = ptrace(UREAD, p->pid, U_AR0, 0); 258 ar0val -= U_PAGE; 259 } 260 #endif 261 for (i = 0; i < NREG; i++) { 262 p->reg[i] = ptrace(UREAD, p->pid, regloc(rloc[i]), 0); 263 p->oreg[i] = p->reg[i]; 264 } 265 #ifdef vax 266 p->fp = p->ofp = ptrace(UREAD, p->pid, regloc(FP), 0); 267 p->ap = p->oap = ptrace(UREAD, p->pid, regloc(AP), 0); 268 p->sp = p->osp = ptrace(UREAD, p->pid, regloc(SP), 0); 269 p->pc = p->opc = ptrace(UREAD, p->pid, regloc(PC), 0); 270 #else 271 p->fp = p->ofp = ptrace(UREAD, p->pid, regloc(AR6), 0); 272 p->ap = p->oap = p->fp; 273 p->sp = p->osp = ptrace(UREAD, p->pid, regloc(SP), 0); 274 p->pc = p->opc = ptrace(UREAD, p->pid, regloc(PC), 0); 275 #endif 276 } 277 278 /* 279 * set process's user area information from given PROCESS structure 280 */ 281 282 LOCAL setinfo(p) 283 register PROCESS *p; 284 { 285 register int i; 286 register int r; 287 288 if (istraced(p)) { 289 p->signo = 0; 290 } 291 for (i = 0; i < NREG; i++) { 292 if ((r = p->reg[i]) != p->oreg[i]) { 293 ptrace(UWRITE, p->pid, regloc(rloc[i]), r); 294 } 295 } 296 #if vax 297 if ((r = p->fp) != p->ofp) { 298 ptrace(UWRITE, p->pid, regloc(FP), r); 299 } 300 if ((r = p->sp) != p->osp) { 301 ptrace(UWRITE, p->pid, regloc(SP), r); 302 } 303 if ((r = p->ap) != p->oap) { 304 ptrace(UWRITE, p->pid, regloc(AP), r); 305 } 306 #else 307 if ((r = p->fp) != p->ofp) { 308 ptrace(UWRITE, p->pid, regloc(AR6), r); 309 } 310 if ((r = p->sp) != p->osp) { 311 ptrace(UWRITE, p->pid, regloc(SP), r); 312 } 313 #endif 314 if ((r = p->pc) != p->opc) { 315 ptrace(UWRITE, p->pid, regloc(PC), r); 316 } 317 } 318 319 /* 320 * Structure for reading and writing by words, but dealing with bytes. 321 */ 322 323 typedef union { 324 WORD pword; 325 BYTE pbyte[sizeof(WORD)]; 326 } PWORD; 327 328 /* 329 * Read (write) from (to) the process' address space. 330 * We must deal with ptrace's inability to look anywhere other 331 * than at a word boundary. 332 */ 333 334 LOCAL WORD fetch(); 335 LOCAL store(); 336 337 pio(p, op, seg, buff, addr, nbytes) 338 PROCESS *p; 339 PIO_OP op; 340 PIO_SEG seg; 341 char *buff; 342 ADDRESS addr; 343 int nbytes; 344 { 345 register int i; 346 register ADDRESS newaddr; 347 register char *cp; 348 char *bufend; 349 PWORD w; 350 ADDRESS wordaddr; 351 int byteoff; 352 353 if (p->status != STOPPED) { 354 error("program is not active"); 355 } 356 cp = buff; 357 newaddr = addr; 358 wordaddr = (newaddr&WMASK); 359 if (wordaddr != newaddr) { 360 w.pword = fetch(p, seg, wordaddr); 361 for (i = newaddr - wordaddr; i<sizeof(WORD) && nbytes>0; i++) { 362 if (op == PREAD) { 363 *cp++ = w.pbyte[i]; 364 } else { 365 w.pbyte[i] = *cp++; 366 } 367 nbytes--; 368 } 369 if (op == PWRITE) { 370 store(p, seg, wordaddr, w.pword); 371 } 372 newaddr = wordaddr + sizeof(WORD); 373 } 374 byteoff = (nbytes&(~WMASK)); 375 nbytes -= byteoff; 376 bufend = cp + nbytes; 377 while (cp < bufend) { 378 if (op == PREAD) { 379 *((WORD *) cp) = fetch(p, seg, newaddr); 380 } else { 381 store(p, seg, newaddr, *((WORD *) cp)); 382 } 383 cp += sizeof(WORD); 384 newaddr += sizeof(WORD); 385 } 386 if (byteoff > 0) { 387 w.pword = fetch(p, seg, newaddr); 388 for (i = 0; i < byteoff; i++) { 389 if (op == PREAD) { 390 *cp++ = w.pbyte[i]; 391 } else { 392 w.pbyte[i] = *cp++; 393 } 394 } 395 if (op == PWRITE) { 396 store(p, seg, newaddr, w.pword); 397 } 398 } 399 } 400 401 /* 402 * Get a word from a process at the given address. 403 * The address is assumed to be on a word boundary. 404 * 405 * We use a simple cache scheme to avoid redundant references to 406 * the instruction space (which is assumed to be pure). In the 407 * case of px, the "instruction" space lies between ENDOFF and 408 * ENDOFF + objsize. 409 * 410 * It is necessary to use a write-through scheme so that 411 * breakpoints right next to each other don't interfere. 412 */ 413 414 LOCAL WORD fetch(p, seg, addr) 415 PROCESS *p; 416 PIO_SEG seg; 417 register int addr; 418 { 419 register CACHEWORD *wp; 420 register WORD w; 421 422 switch (seg) { 423 case TEXTSEG: 424 # if (isvaxpx) 425 panic("tried to fetch from px i-space"); 426 /* NOTREACHED */ 427 # else 428 wp = &p->word[cachehash(addr)]; 429 if (addr == 0 || wp->addr != addr) { 430 w = ptrace(IREAD, p->pid, addr, 0); 431 wp->addr = addr; 432 wp->val = w; 433 } else { 434 w = wp->val; 435 } 436 break; 437 # endif 438 439 case DATASEG: 440 # if (isvaxpx) 441 if (addr >= ENDOFF && addr < ENDOFF + objsize) { 442 wp = &p->word[cachehash(addr)]; 443 if (addr == 0 || wp->addr != addr) { 444 w = ptrace(DREAD, p->pid, addr, 0); 445 wp->addr = addr; 446 wp->val = w; 447 } else { 448 w = wp->val; 449 } 450 } else { 451 w = ptrace(DREAD, p->pid, addr, 0); 452 } 453 # else 454 w = ptrace(DREAD, p->pid, addr, 0); 455 # endif 456 break; 457 458 default: 459 panic("fetch: bad seg %d", seg); 460 /* NOTREACHED */ 461 } 462 return(w); 463 } 464 465 /* 466 * Put a word into the process' address space at the given address. 467 * The address is assumed to be on a word boundary. 468 */ 469 470 LOCAL store(p, seg, addr, data) 471 PROCESS *p; 472 PIO_SEG seg; 473 int addr; 474 WORD data; 475 { 476 register CACHEWORD *wp; 477 478 switch (seg) { 479 case TEXTSEG: 480 wp = &p->word[cachehash(addr)]; 481 wp->addr = addr; 482 wp->val = data; 483 ptrace(IWRITE, p->pid, addr, data); 484 break; 485 486 case DATASEG: 487 # if (isvaxpx) 488 if (addr >= ENDOFF && addr < ENDOFF + objsize) { 489 wp = &p->word[cachehash(addr)]; 490 wp->addr = addr; 491 wp->val = data; 492 } 493 # endif 494 ptrace(DWRITE, p->pid, addr, data); 495 break; 496 497 default: 498 panic("store: bad seg %d", seg); 499 /*NOTREACHED*/ 500 } 501 } 502 503 /* 504 * Initialize the instruction cache for a process. 505 * This is particularly necessary after the program has been remade. 506 */ 507 508 initcache(process) 509 PROCESS *process; 510 { 511 register int i; 512 513 for (i = 0; i < CSIZE; i++) { 514 process->word[i].addr = 0; 515 } 516 } 517 518 /* 519 * Swap file numbers so as to redirect standard input and output. 520 */ 521 522 LOCAL fswap(oldfd, newfd) 523 int oldfd; 524 int newfd; 525 { 526 if (oldfd != newfd) { 527 close(oldfd); 528 dup(newfd); 529 close(newfd); 530 } 531 } 532