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