util.c revision 7b3082206c5ea5ea41259c8b013138c6f6b6463a
1/* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Linux for s390 port by D.J. Barrow 8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com> 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $Id$ 34 */ 35 36#include "defs.h" 37 38#include <signal.h> 39#include <sys/syscall.h> 40#include <sys/user.h> 41#include <sys/param.h> 42#include <fcntl.h> 43#if HAVE_SYS_UIO_H 44#include <sys/uio.h> 45#endif 46#ifdef SUNOS4 47#include <machine/reg.h> 48#include <a.out.h> 49#include <link.h> 50#endif /* SUNOS4 */ 51 52#if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1)) 53#include <linux/ptrace.h> 54#endif 55 56#if defined(LINUX) && defined(IA64) 57# include <asm/ptrace_offsets.h> 58# include <asm/rse.h> 59#endif 60 61#ifdef HAVE_SYS_REG_H 62#include <sys/reg.h> 63# define PTRACE_PEEKUSR PTRACE_PEEKUSER 64#elif defined(HAVE_LINUX_PTRACE_H) 65#undef PTRACE_SYSCALL 66#include <linux/ptrace.h> 67#endif 68 69#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 70#include <sys/utsname.h> 71#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 72 73#if defined(LINUX) && defined(SPARC) 74 75#include <asm/reg.h> 76 77#if !defined(__GLIBC__) 78 79#include <linux/unistd.h> 80 81#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\ 82 type5,arg5,syscall) \ 83type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ 84{ \ 85 long __res; \ 86\ 87__asm__ volatile ("or %%g0, %1, %%o0\n\t" \ 88 "or %%g0, %2, %%o1\n\t" \ 89 "or %%g0, %3, %%o2\n\t" \ 90 "or %%g0, %4, %%o3\n\t" \ 91 "or %%g0, %5, %%o4\n\t" \ 92 "or %%g0, %6, %%g1\n\t" \ 93 "t 0x10\n\t" \ 94 "bcc 1f\n\t" \ 95 "or %%g0, %%o0, %0\n\t" \ 96 "sub %%g0, %%o0, %0\n\t" \ 97 "1:\n\t" \ 98 : "=r" (__res) \ 99 : "0" ((long)(arg1)),"1" ((long)(arg2)), \ 100 "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \ 101 "i" (__NR_##syscall) \ 102 : "g1", "o0", "o1", "o2", "o3", "o4"); \ 103if (__res>=0) \ 104 return (type) __res; \ 105errno = -__res; \ 106return -1; \ 107} 108 109static _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace) 110 111#define _ptrace 112 113#endif 114 115#endif 116 117/* macros */ 118#ifndef MAX 119#define MAX(a,b) (((a) > (b)) ? (a) : (b)) 120#endif 121#ifndef MIN 122#define MIN(a,b) (((a) < (b)) ? (a) : (b)) 123#endif 124 125void 126tv_tv(tv, a, b) 127struct timeval *tv; 128int a; 129int b; 130{ 131 tv->tv_sec = a; 132 tv->tv_usec = b; 133} 134 135int 136tv_nz(a) 137struct timeval *a; 138{ 139 return a->tv_sec || a->tv_usec; 140} 141 142int 143tv_cmp(a, b) 144struct timeval *a, *b; 145{ 146 if (a->tv_sec < b->tv_sec 147 || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) 148 return -1; 149 if (a->tv_sec > b->tv_sec 150 || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec)) 151 return 1; 152 return 0; 153} 154 155double 156tv_float(tv) 157struct timeval *tv; 158{ 159 return tv->tv_sec + tv->tv_usec/1000000.0; 160} 161 162void 163tv_add(tv, a, b) 164struct timeval *tv, *a, *b; 165{ 166 tv->tv_sec = a->tv_sec + b->tv_sec; 167 tv->tv_usec = a->tv_usec + b->tv_usec; 168 if (tv->tv_usec > 1000000) { 169 tv->tv_sec++; 170 tv->tv_usec -= 1000000; 171 } 172} 173 174void 175tv_sub(tv, a, b) 176struct timeval *tv, *a, *b; 177{ 178 tv->tv_sec = a->tv_sec - b->tv_sec; 179 tv->tv_usec = a->tv_usec - b->tv_usec; 180 if (((long) tv->tv_usec) < 0) { 181 tv->tv_sec--; 182 tv->tv_usec += 1000000; 183 } 184} 185 186void 187tv_div(tv, a, n) 188struct timeval *tv, *a; 189int n; 190{ 191 tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n; 192 tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000; 193 tv->tv_usec %= 1000000; 194} 195 196void 197tv_mul(tv, a, n) 198struct timeval *tv, *a; 199int n; 200{ 201 tv->tv_usec = a->tv_usec * n; 202 tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000; 203 tv->tv_usec %= 1000000; 204} 205 206char * 207xlookup(xlat, val) 208struct xlat *xlat; 209int val; 210{ 211 for (; xlat->str != NULL; xlat++) 212 if (xlat->val == val) 213 return xlat->str; 214 return NULL; 215} 216 217/* 218 * Print entry in struct xlat table, if there. 219 */ 220void 221printxval(xlat, val, dflt) 222struct xlat *xlat; 223int val; 224char *dflt; 225{ 226 char *str = xlookup(xlat, val); 227 228 if (str) 229 tprintf("%s", str); 230 else 231 tprintf("%#x /* %s */", val, dflt); 232} 233 234/* 235 * Interpret `xlat' as an array of flags 236 * print the entries whose bits are on in `flags' 237 * return # of flags printed. 238 */ 239int 240addflags(xlat, flags) 241struct xlat *xlat; 242int flags; 243{ 244 int n; 245 246 for (n = 0; xlat->str; xlat++) { 247 if (xlat->val && (flags & xlat->val) == xlat->val) { 248 tprintf("|%s", xlat->str); 249 flags &= ~xlat->val; 250 n++; 251 } 252 } 253 if (flags) { 254 tprintf("|%#x", flags); 255 n++; 256 } 257 return n; 258} 259 260int 261printflags(xlat, flags) 262struct xlat *xlat; 263int flags; 264{ 265 int n; 266 char *sep; 267 268 if (flags == 0 && xlat->val == 0) { 269 tprintf("%s", xlat->str); 270 return 1; 271 } 272 273 sep = ""; 274 for (n = 0; xlat->str; xlat++) { 275 if (xlat->val && (flags & xlat->val) == xlat->val) { 276 tprintf("%s%s", sep, xlat->str); 277 flags &= ~xlat->val; 278 sep = "|"; 279 n++; 280 } 281 } 282 if (flags) { 283 tprintf("%s%#x", sep, flags); 284 n++; 285 } 286 return n; 287} 288 289void 290printnum(tcp, addr, fmt) 291struct tcb *tcp; 292long addr; 293char *fmt; 294{ 295 long num; 296 297 if (!addr) { 298 tprintf("NULL"); 299 return; 300 } 301 if (umove(tcp, addr, &num) < 0) { 302 tprintf("%#lx", addr); 303 return; 304 } 305 tprintf("["); 306 tprintf(fmt, num); 307 tprintf("]"); 308} 309 310static char path[MAXPATHLEN + 1]; 311 312void 313string_quote(str) 314char *str; 315{ 316 char buf[2 * MAXPATHLEN + 1]; 317 char *s; 318 319 if (!strpbrk(str, "\"\'\\")) { 320 tprintf("\"%s\"", str); 321 return; 322 } 323 for (s = buf; *str; str++) { 324 switch (*str) { 325 case '\"': case '\'': case '\\': 326 *s++ = '\\'; *s++ = *str; break; 327 default: 328 *s++ = *str; break; 329 } 330 } 331 *s = '\0'; 332 tprintf("\"%s\"", buf); 333} 334 335void 336printpath(tcp, addr) 337struct tcb *tcp; 338long addr; 339{ 340 if (umovestr(tcp, addr, MAXPATHLEN, path) < 0) 341 tprintf("%#lx", addr); 342 else 343 string_quote(path); 344 return; 345} 346 347void 348printpathn(tcp, addr, n) 349struct tcb *tcp; 350long addr; 351int n; 352{ 353 if (umovestr(tcp, addr, n, path) < 0) 354 tprintf("%#lx", addr); 355 else { 356 path[n] = '\0'; 357 string_quote(path); 358 } 359} 360 361void 362printstr(tcp, addr, len) 363struct tcb *tcp; 364long addr; 365int len; 366{ 367 static unsigned char *str = NULL; 368 static char *outstr; 369 int i, n, c, usehex; 370 char *s, *outend; 371 372 if (!addr) { 373 tprintf("NULL"); 374 return; 375 } 376 if (!str) { 377 if ((str = malloc(max_strlen)) == NULL 378 || (outstr = malloc(2*max_strlen)) == NULL) { 379 fprintf(stderr, "printstr: no memory\n"); 380 tprintf("%#lx", addr); 381 return; 382 } 383 } 384 outend = outstr + max_strlen * 2 - 10; 385 if (len < 0) { 386 n = max_strlen; 387 if (umovestr(tcp, addr, n, (char *) str) < 0) { 388 tprintf("%#lx", addr); 389 return; 390 } 391 } 392 else { 393 n = MIN(len, max_strlen); 394 if (umoven(tcp, addr, n, (char *) str) < 0) { 395 tprintf("%#lx", addr); 396 return; 397 } 398 } 399 400 usehex = 0; 401 if (xflag > 1) 402 usehex = 1; 403 else if (xflag) { 404 for (i = 0; i < n; i++) { 405 c = str[i]; 406 if (len < 0 && c == '\0') 407 break; 408 if (!isprint(c) && !isspace(c)) { 409 usehex = 1; 410 break; 411 } 412 } 413 } 414 415 s = outstr; 416 *s++ = '\"'; 417 418 if (usehex) { 419 for (i = 0; i < n; i++) { 420 c = str[i]; 421 if (len < 0 && c == '\0') 422 break; 423 sprintf(s, "\\x%02x", c); 424 s += 4; 425 if (s > outend) 426 break; 427 } 428 } 429 else { 430 for (i = 0; i < n; i++) { 431 c = str[i]; 432 if (len < 0 && c == '\0') 433 break; 434 switch (c) { 435 case '\"': case '\'': case '\\': 436 *s++ = '\\'; *s++ = c; break; 437 case '\f': 438 *s++ = '\\'; *s++ = 'f'; break; 439 case '\n': 440 *s++ = '\\'; *s++ = 'n'; break; 441 case '\r': 442 *s++ = '\\'; *s++ = 'r'; break; 443 case '\t': 444 *s++ = '\\'; *s++ = 't'; break; 445 case '\v': 446 *s++ = '\\'; *s++ = 'v'; break; 447 default: 448 if (isprint(c)) 449 *s++ = c; 450 else if (i < n - 1 && isdigit(str[i + 1])) { 451 sprintf(s, "\\%03o", c); 452 s += 4; 453 } 454 else { 455 sprintf(s, "\\%o", c); 456 s += strlen(s); 457 } 458 break; 459 } 460 if (s > outend) 461 break; 462 } 463 } 464 465 *s++ = '\"'; 466 if (i < len || (len < 0 && (i == n || s > outend))) { 467 *s++ = '.'; *s++ = '.'; *s++ = '.'; 468 } 469 *s = '\0'; 470 tprintf("%s", outstr); 471} 472 473#if HAVE_SYS_UIO_H 474void 475dumpiov(tcp, len, addr) 476struct tcb * tcp; 477int len; 478long addr; 479{ 480 struct iovec *iov; 481 int i; 482 483 484 if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) { 485 fprintf(stderr, "dump: No memory"); 486 return; 487 } 488 if (umoven(tcp, addr, 489 len * sizeof *iov, (char *) iov) >= 0) { 490 491 for (i = 0; i < len; i++) { 492 /* include the buffer number to make it easy to 493 * match up the trace with the source */ 494 tprintf(" * %lu bytes in buffer %d\n", 495 (unsigned long)iov[i].iov_len, i); 496 dumpstr(tcp, (long) iov[i].iov_base, 497 iov[i].iov_len); 498 } 499 } 500 free((char *) iov); 501 502} 503#endif 504 505void 506dumpstr(tcp, addr, len) 507struct tcb *tcp; 508long addr; 509int len; 510{ 511 static int strsize = -1; 512 static unsigned char *str; 513 static char outstr[80]; 514 char *s; 515 int i, j; 516 517 if (strsize < len) { 518 if (str) 519 free(str); 520 if ((str = malloc(len)) == NULL) { 521 fprintf(stderr, "dump: no memory\n"); 522 return; 523 } 524 strsize = len; 525 } 526 527 if (umoven(tcp, addr, len, (char *) str) < 0) 528 return; 529 530 for (i = 0; i < len; i += 16) { 531 s = outstr; 532 sprintf(s, " | %05x ", i); 533 s += 9; 534 for (j = 0; j < 16; j++) { 535 if (j == 8) 536 *s++ = ' '; 537 if (i + j < len) { 538 sprintf(s, " %02x", str[i + j]); 539 s += 3; 540 } 541 else { 542 *s++ = ' '; *s++ = ' '; *s++ = ' '; 543 } 544 } 545 *s++ = ' '; *s++ = ' '; 546 for (j = 0; j < 16; j++) { 547 if (j == 8) 548 *s++ = ' '; 549 if (i + j < len) { 550 if (isprint(str[i + j])) 551 *s++ = str[i + j]; 552 else 553 *s++ = '.'; 554 } 555 else 556 *s++ = ' '; 557 } 558 tprintf("%s |\n", outstr); 559 } 560} 561 562#define PAGMASK (~(PAGSIZ - 1)) 563/* 564 * move `len' bytes of data from process `pid' 565 * at address `addr' to our space at `laddr' 566 */ 567int 568umoven(tcp, addr, len, laddr) 569struct tcb *tcp; 570long addr; 571int len; 572char *laddr; 573{ 574 575#ifdef LINUX 576 int pid = tcp->pid; 577 int n, m; 578 int started = 0; 579 union { 580 long val; 581 char x[sizeof(long)]; 582 } u; 583 584 if (addr & (sizeof(long) - 1)) { 585 /* addr not a multiple of sizeof(long) */ 586 n = addr - (addr & -sizeof(long)); /* residue */ 587 addr &= -sizeof(long); /* residue */ 588 errno = 0; 589 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 590 if (errno) { 591 if (started && (errno==EPERM || errno==EIO)) { 592 /* Ran into 'end of memory' - stupid "printpath" */ 593 return 0; 594 } 595 /* But if not started, we had a bogus address. */ 596 perror("ptrace: umoven"); 597 return -1; 598 } 599 started = 1; 600 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 601 addr += sizeof(long), laddr += m, len -= m; 602 } 603 while (len) { 604 errno = 0; 605 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 606 if (errno) { 607 if (started && (errno==EPERM || errno==EIO)) { 608 /* Ran into 'end of memory' - stupid "printpath" */ 609 return 0; 610 } 611 perror("ptrace: umoven"); 612 return -1; 613 } 614 started = 1; 615 memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 616 addr += sizeof(long), laddr += m, len -= m; 617 } 618#endif /* LINUX */ 619 620#ifdef SUNOS4 621 int pid = tcp->pid; 622#if 0 623 int n, m; 624 union { 625 long val; 626 char x[sizeof(long)]; 627 } u; 628 629 if (addr & (sizeof(long) - 1)) { 630 /* addr not a multiple of sizeof(long) */ 631 n = addr - (addr & -sizeof(long)); /* residue */ 632 addr &= -sizeof(long); /* residue */ 633 errno = 0; 634 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 635 if (errno) { 636 perror("umoven"); 637 return -1; 638 } 639 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 640 addr += sizeof(long), laddr += m, len -= m; 641 } 642 while (len) { 643 errno = 0; 644 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 645 if (errno) { 646 perror("umoven"); 647 return -1; 648 } 649 memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 650 addr += sizeof(long), laddr += m, len -= m; 651 } 652#else /* !oldway */ 653 int n; 654 655 while (len) { 656 n = MIN(len, PAGSIZ); 657 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 658 if (ptrace(PTRACE_READDATA, pid, 659 (char *) addr, len, laddr) < 0) { 660 perror("umoven: ptrace(PTRACE_READDATA, ...)"); 661 abort(); 662 return -1; 663 } 664 len -= n; 665 addr += n; 666 laddr += n; 667 } 668#endif /* !oldway */ 669#endif /* SUNOS4 */ 670 671#ifdef USE_PROCFS 672#ifdef HAVE_MP_PROCFS 673 int fd = tcp->pfd_as; 674#else 675 int fd = tcp->pfd; 676#endif 677 lseek(fd, addr, SEEK_SET); 678 if (read(fd, laddr, len) == -1) 679 return -1; 680#endif /* USE_PROCFS */ 681 682 return 0; 683} 684 685/* 686 * like `umove' but make the additional effort of looking 687 * for a terminating zero byte. 688 */ 689int 690umovestr(tcp, addr, len, laddr) 691struct tcb *tcp; 692long addr; 693int len; 694char *laddr; 695{ 696#ifdef USE_PROCFS 697#ifdef HAVE_MP_PROCFS 698 int fd = tcp->pfd_as; 699#else 700 int fd = tcp->pfd; 701#endif 702 /* Some systems (e.g. FreeBSD) can be upset if we read off the 703 end of valid memory, avoid this by trying to read up 704 to page boundaries. But we don't know what a page is (and 705 getpagesize(2) (if it exists) doesn't necessarily return 706 hardware page size). Assume all pages >= 1024 (a-historical 707 I know) */ 708 709 int page = 1024; /* How to find this? */ 710 int move = page - (addr & (page - 1)); 711 int left = len; 712 713 lseek(fd, addr, SEEK_SET); 714 715 while (left) { 716 if (move > left) move = left; 717 if ((move = read(fd, laddr, move)) <= 0) 718 return left != len ? 0 : -1; 719 if (memchr (laddr, 0, move)) break; 720 left -= move; 721 laddr += move; 722 addr += move; 723 move = page; 724 } 725#else /* !USE_PROCFS */ 726 int started = 0; 727 int pid = tcp->pid; 728 int i, n, m; 729 union { 730 long val; 731 char x[sizeof(long)]; 732 } u; 733 734 if (addr & (sizeof(long) - 1)) { 735 /* addr not a multiple of sizeof(long) */ 736 n = addr - (addr & -sizeof(long)); /* residue */ 737 addr &= -sizeof(long); /* residue */ 738 errno = 0; 739 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 740 if (errno) { 741 if (started && (errno==EPERM || errno==EIO)) { 742 /* Ran into 'end of memory' - stupid "printpath" */ 743 return 0; 744 } 745 perror("umovestr"); 746 return -1; 747 } 748 started = 1; 749 memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len)); 750 while (n & (sizeof(long) - 1)) 751 if (u.x[n++] == '\0') 752 return 0; 753 addr += sizeof(long), laddr += m, len -= m; 754 } 755 while (len) { 756 errno = 0; 757 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 758 if (errno) { 759 if (started && (errno==EPERM || errno==EIO)) { 760 /* Ran into 'end of memory' - stupid "printpath" */ 761 return 0; 762 } 763 perror("umovestr"); 764 return -1; 765 } 766 started = 1; 767 memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 768 for (i = 0; i < sizeof(long); i++) 769 if (u.x[i] == '\0') 770 return 0; 771 772 addr += sizeof(long), laddr += m, len -= m; 773 } 774#endif /* !USE_PROCFS */ 775 return 0; 776} 777 778#ifdef LINUX 779#ifndef SPARC 780#define PTRACE_WRITETEXT 101 781#define PTRACE_WRITEDATA 102 782#endif /* !SPARC */ 783#endif /* LINUX */ 784 785#ifdef SUNOS4 786 787static int 788uload(cmd, pid, addr, len, laddr) 789int cmd; 790int pid; 791long addr; 792int len; 793char *laddr; 794{ 795#if 0 796 int n; 797 798 while (len) { 799 n = MIN(len, PAGSIZ); 800 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 801 if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) { 802 perror("uload: ptrace(PTRACE_WRITE, ...)"); 803 return -1; 804 } 805 len -= n; 806 addr += n; 807 laddr += n; 808 } 809#else 810 int peek, poke; 811 int n, m; 812 union { 813 long val; 814 char x[sizeof(long)]; 815 } u; 816 817 if (cmd == PTRACE_WRITETEXT) { 818 peek = PTRACE_PEEKTEXT; 819 poke = PTRACE_POKETEXT; 820 } 821 else { 822 peek = PTRACE_PEEKDATA; 823 poke = PTRACE_POKEDATA; 824 } 825 if (addr & (sizeof(long) - 1)) { 826 /* addr not a multiple of sizeof(long) */ 827 n = addr - (addr & -sizeof(long)); /* residue */ 828 addr &= -sizeof(long); 829 errno = 0; 830 u.val = ptrace(peek, pid, (char *) addr, 0); 831 if (errno) { 832 perror("uload: POKE"); 833 return -1; 834 } 835 memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len)); 836 if (ptrace(poke, pid, (char *)addr, u.val) < 0) { 837 perror("uload: POKE"); 838 return -1; 839 } 840 addr += sizeof(long), laddr += m, len -= m; 841 } 842 while (len) { 843 if (len < sizeof(long)) 844 u.val = ptrace(peek, pid, (char *) addr, 0); 845 memcpy(u.x, laddr, m = MIN(sizeof(long), len)); 846 if (ptrace(poke, pid, (char *) addr, u.val) < 0) { 847 perror("uload: POKE"); 848 return -1; 849 } 850 addr += sizeof(long), laddr += m, len -= m; 851 } 852#endif 853 return 0; 854} 855 856int 857tload(pid, addr, len, laddr) 858int pid; 859int addr, len; 860char *laddr; 861{ 862 return uload(PTRACE_WRITETEXT, pid, addr, len, laddr); 863} 864 865int 866dload(pid, addr, len, laddr) 867int pid; 868int addr; 869int len; 870char *laddr; 871{ 872 return uload(PTRACE_WRITEDATA, pid, addr, len, laddr); 873} 874 875#endif /* SUNOS4 */ 876 877#ifndef USE_PROCFS 878 879int 880upeek(pid, off, res) 881int pid; 882long off; 883long *res; 884{ 885 long val; 886 887#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 888 { 889 static int is_sun4m = -1; 890 struct utsname name; 891 892 /* Round up the usual suspects. */ 893 if (is_sun4m == -1) { 894 if (uname(&name) < 0) { 895 perror("upeek: uname?"); 896 exit(1); 897 } 898 is_sun4m = strcmp(name.machine, "sun4m") == 0; 899 if (is_sun4m) { 900 extern struct xlat struct_user_offsets[]; 901 struct xlat *x; 902 903 for (x = struct_user_offsets; x->str; x++) 904 x->val += 1024; 905 } 906 } 907 if (is_sun4m) 908 off += 1024; 909 } 910#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 911 errno = 0; 912 val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0); 913 if (val == -1 && errno) { 914 char buf[60]; 915 sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)",pid,off); 916 perror(buf); 917 return -1; 918 } 919 *res = val; 920 return 0; 921} 922 923#endif /* !USE_PROCFS */ 924 925long 926getpc(tcp) 927struct tcb *tcp; 928{ 929 930#ifdef LINUX 931 long pc; 932#if defined(I386) 933 if (upeek(tcp->pid, 4*EIP, &pc) < 0) 934 return -1; 935#elif defined(X86_64) 936 if (upeek(tcp->pid, 8*RIP, &pc) < 0) 937 return -1; 938#elif defined(IA64) 939 if (upeek(tcp->pid, PT_B0, &pc) < 0) 940 return -1; 941#elif defined(ARM) 942 if (upeek(tcp->pid, 4*15, &pc) < 0) 943 return -1; 944#elif defined(POWERPC) 945 if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) 946 return -1; 947#elif defined(M68k) 948 if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 949 return -1; 950#elif defined(ALPHA) 951 if (upeek(tcp->pid, REG_PC, &pc) < 0) 952 return -1; 953#elif defined(MIPS) 954 if (upeek(tcp->pid, REG_EPC, &pc) < 0) 955 return -1; 956#elif defined(SPARC) 957 struct regs regs; 958 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) 959 return -1; 960 pc = regs.r_pc; 961#elif defined(S390) || defined(S390X) 962 if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0) 963 return -1; 964#elif defined(HPPA) 965 if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) 966 return -1; 967#elif defined(SH) 968 if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0) 969 return -1; 970#endif 971 return pc; 972#endif /* LINUX */ 973 974#ifdef SUNOS4 975 /* 976 * Return current program counter for `pid' 977 * Assumes PC is never 0xffffffff 978 */ 979 struct regs regs; 980 981 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 982 perror("getpc: ptrace(PTRACE_GETREGS, ...)"); 983 return -1; 984 } 985 return regs.r_pc; 986#endif /* SUNOS4 */ 987 988#ifdef SVR4 989 /* XXX */ 990 return 0; 991#endif /* SVR4 */ 992 993#ifdef FREEBSD 994 struct reg regs; 995 pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 996 return regs.r_eip; 997#endif /* FREEBSD */ 998} 999 1000void 1001printcall(tcp) 1002struct tcb *tcp; 1003{ 1004 1005#ifdef LINUX 1006#ifdef I386 1007 long eip; 1008 1009 if (upeek(tcp->pid, 4*EIP, &eip) < 0) { 1010 tprintf("[????????] "); 1011 return; 1012 } 1013 tprintf("[%08lx] ", eip); 1014#elif defined(X86_64) 1015 long rip; 1016 1017 if (upeek(tcp->pid, 8*RIP, &rip) < 0) { 1018 tprintf("[????????] "); 1019 return; 1020 } 1021 tprintf("[%16lx] ", rip); 1022#elif defined(IA62) 1023 long ip; 1024 1025 if (upeek(tcp->pid, PT_B0, &ip) < 0) { 1026 tprintf("[????????] "); 1027 return; 1028 } 1029 tprintf("[%08lx] ", ip); 1030#elif defined(POWERPC) 1031 long pc; 1032 1033 if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) { 1034 tprintf ("[????????] "); 1035 return; 1036 } 1037 tprintf("[%08lx] ", pc); 1038#elif defined(M68k) 1039 long pc; 1040 1041 if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) { 1042 tprintf ("[????????] "); 1043 return; 1044 } 1045 tprintf("[%08lx] ", pc); 1046#elif defined(ALPHA) 1047 long pc; 1048 1049 if (upeek(tcp->pid, REG_PC, &pc) < 0) { 1050 tprintf ("[????????] "); 1051 return; 1052 } 1053 tprintf("[%08lx] ", pc); 1054#elif defined(SPARC) 1055 struct regs regs; 1056 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) { 1057 tprintf("[????????] "); 1058 return; 1059 } 1060 tprintf("[%08lx] ", regs.r_pc); 1061#elif defined(HPPA) 1062 long pc; 1063 1064 if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) { 1065 tprintf ("[????????] "); 1066 return; 1067 } 1068 tprintf("[%08lx] ", pc); 1069#elif defined(MIPS) 1070 long pc; 1071 1072 if (upeek(tcp->pid, REG_EPC, &pc) < 0) { 1073 tprintf ("[????????] "); 1074 return; 1075 } 1076 tprintf("[%08lx] ", pc); 1077#elif defined(SH) 1078 long pc; 1079 1080 if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) { 1081 tprintf ("[????????] "); 1082 return; 1083 } 1084 tprintf("[%08lx] ", pc); 1085#endif /* !architecture */ 1086#endif /* LINUX */ 1087 1088#ifdef SUNOS4 1089 struct regs regs; 1090 1091 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 1092 perror("printcall: ptrace(PTRACE_GETREGS, ...)"); 1093 tprintf("[????????] "); 1094 return; 1095 } 1096 tprintf("[%08x] ", regs.r_o7); 1097#endif /* SUNOS4 */ 1098 1099#ifdef SVR4 1100 /* XXX */ 1101 tprintf("[????????] "); 1102#endif 1103 1104#ifdef FREEBSD 1105 struct reg regs; 1106 pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1107 tprintf("[%08x] ", regs.r_eip); 1108#endif /* FREEBSD */ 1109} 1110 1111#ifndef USE_PROCFS 1112 1113#if defined LINUX 1114 1115#include <sys/syscall.h> 1116#ifndef CLONE_PTRACE 1117# define CLONE_PTRACE 0x00002000 1118#endif 1119 1120#ifdef IA64 1121 1122typedef unsigned long *arg_setup_state; 1123 1124static int 1125arg_setup(struct tcb *tcp, arg_setup_state *state) 1126{ 1127 unsigned long *bsp, cfm, sof, sol; 1128 1129 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) < 0) 1130 return -1; 1131 if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0) 1132 return -1; 1133 1134 sof = (cfm >> 0) & 0x7f; 1135 sol = (cfm >> 7) & 0x7f; 1136 bsp = ia64_rse_skip_regs(bsp, -sof + sol); 1137 1138 *state = bsp; 1139 return 0; 1140} 1141 1142# define arg_finish_change(tcp, state) 0 1143 1144#ifdef SYS_fork 1145static int 1146get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp) 1147{ 1148 return umoven (tcp, (unsigned long) ia64_rse_skip_regs(*state, 0), 1149 sizeof(long), (void *) valp); 1150} 1151 1152static int 1153get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp) 1154{ 1155 return umoven (tcp, (unsigned long) ia64_rse_skip_regs(*state, 1), 1156 sizeof(long), (void *) valp); 1157} 1158#endif 1159 1160static int 1161set_arg0 (struct tcb *tcp, arg_setup_state *state, long val) 1162{ 1163 unsigned long *ap; 1164 ap = ia64_rse_skip_regs(*state, 0); 1165 errno = 0; 1166 ptrace(PTRACE_POKEDATA, tcp->pid, (void *) ap, val); 1167 return errno ? -1 : 0; 1168} 1169 1170static int 1171set_arg1 (struct tcb *tcp, arg_setup_state *state, long val) 1172{ 1173 unsigned long *ap; 1174 ap = ia64_rse_skip_regs(*state, 1); 1175 errno = 0; 1176 ptrace(PTRACE_POKEDATA, tcp->pid, (void *) ap, val); 1177 return errno ? -1 : 0; 1178} 1179 1180#elif defined (SPARC) 1181 1182typedef struct regs arg_setup_state; 1183 1184# define arg_setup(tcp, state) \ 1185 (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0)) 1186# define arg_finish_change(tcp, state) \ 1187 (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0)) 1188 1189# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0) 1190# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0) 1191# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0) 1192# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0) 1193# define restore_arg0(tcp, state, val) 0 1194 1195#else 1196 1197# if defined S390 || defined S390X 1198/* Note: this is only true for the `clone' system call, which handles 1199 arguments specially. We could as well say that its first two arguments 1200 are swapped relative to other architectures, but that would just be 1201 another #ifdef in the calls. */ 1202# define arg0_offset PT_GPR3 1203# define arg1_offset PT_ORIGGPR2 1204# define restore_arg0(tcp, state, val) ((void) (state), 0) 1205# define restore_arg1(tcp, state, val) ((void) (state), 0) 1206# elif defined (ALPHA) || defined (MIPS) 1207# define arg0_offset REG_A0 1208# define arg1_offset (REG_A0+1) 1209# elif defined (POWERPC) 1210# define arg0_offset (sizeof(unsigned long)*PT_R3) 1211# define arg1_offset (sizeof(unsigned long)*PT_R4) 1212# define restore_arg0(tcp, state, val) ((void) (state), 0) 1213# elif defined (HPPA) 1214# define arg0_offset PT_GR26 1215# define arg1_offset (PT_GR26-4) 1216# elif defined (X86_64) 1217# define arg0_offset ((long)(8*(current_personality ? RBX : RDI))) 1218# define arg1_offset ((long)(8*(current_personality ? RCX : RSI))) 1219# else 1220# define arg0_offset 0 1221# define arg1_offset 4 1222# if defined SH || defined ARM 1223# define restore_arg0(tcp, state, val) 0 1224# endif 1225# endif 1226 1227typedef int arg_setup_state; 1228 1229# define arg_setup(tcp, state) (0) 1230# define arg_finish_change(tcp, state) 0 1231# define get_arg0(tcp, cookie, valp) \ 1232 (upeek ((tcp)->pid, arg0_offset, (valp))) 1233# define get_arg1(tcp, cookie, valp) \ 1234 (upeek ((tcp)->pid, arg1_offset, (valp))) 1235 1236static int 1237set_arg0 (struct tcb *tcp, void *cookie, long val) 1238{ 1239 return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val); 1240} 1241 1242static int 1243set_arg1 (struct tcb *tcp, void *cookie, long val) 1244{ 1245 return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val); 1246} 1247 1248#endif 1249 1250#ifndef restore_arg0 1251# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val)) 1252#endif 1253#ifndef restore_arg1 1254# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val)) 1255#endif 1256 1257int 1258setbpt(tcp) 1259struct tcb *tcp; 1260{ 1261 extern int change_syscall(struct tcb *, int); 1262 arg_setup_state state; 1263 1264 if (tcp->flags & TCB_BPTSET) { 1265 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1266 return -1; 1267 } 1268 1269 switch (tcp->scno) { 1270#ifdef SYS_vfork 1271 case SYS_vfork: 1272#endif 1273#ifdef SYS_fork 1274 case SYS_fork: 1275#endif 1276#if defined SYS_fork || defined SYS_vfork 1277 if (arg_setup (tcp, &state) < 0 1278 || get_arg0 (tcp, &state, &tcp->inst[0]) < 0 1279 || get_arg1 (tcp, &state, &tcp->inst[1]) < 0 1280 || change_syscall(tcp, SYS_clone) < 0 1281 || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 1282 || set_arg1 (tcp, &state, 0) < 0 1283 || arg_finish_change (tcp, &state) < 0) 1284 return -1; 1285 tcp->u_arg[0] = CLONE_PTRACE|SIGCHLD; 1286 tcp->u_arg[1] = 0; 1287 tcp->flags |= TCB_BPTSET; 1288 return 0; 1289#endif 1290 1291 case SYS_clone: 1292#ifdef SYS_clone2 1293 case SYS_clone2: 1294#endif 1295 if ((tcp->u_arg[0] & CLONE_PTRACE) == 0 1296 && (arg_setup (tcp, &state) < 0 1297 || set_arg0 (tcp, &state, tcp->u_arg[0] | CLONE_PTRACE) < 0 1298 || arg_finish_change (tcp, &state) < 0)) 1299 return -1; 1300 tcp->flags |= TCB_BPTSET; 1301 tcp->inst[0] = tcp->u_arg[0]; 1302 tcp->inst[1] = tcp->u_arg[1]; 1303 return 0; 1304 1305 default: 1306 fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n", 1307 tcp->scno, tcp->pid); 1308 break; 1309 } 1310 1311 return -1; 1312} 1313 1314int 1315clearbpt(tcp) 1316struct tcb *tcp; 1317{ 1318 arg_setup_state state; 1319 if (arg_setup (tcp, &state) < 0 1320 || restore_arg0 (tcp, &state, tcp->inst[0]) < 0 1321 || restore_arg1 (tcp, &state, tcp->inst[1]) < 0 1322 || arg_finish_change (tcp, &state)) 1323 return -1; 1324 tcp->flags &= ~TCB_BPTSET; 1325 return 0; 1326} 1327 1328#else 1329 1330int 1331setbpt(tcp) 1332struct tcb *tcp; 1333{ 1334 1335#ifdef LINUX 1336#ifdef SPARC 1337 /* We simply use the SunOS breakpoint code. */ 1338 1339 struct regs regs; 1340#define LOOPA 0x30800000 /* ba,a 0 */ 1341 1342 if (tcp->flags & TCB_BPTSET) { 1343 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1344 return -1; 1345 } 1346 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1347 perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 1348 return -1; 1349 } 1350 tcp->baddr = regs.r_o7 + 8; 1351 errno = 0; 1352 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0); 1353 if(errno) { 1354 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1355 return -1; 1356 } 1357 1358 /* 1359 * XXX - BRUTAL MODE ON 1360 * We cannot set a real BPT in the child, since it will not be 1361 * traced at the moment it will reach the trap and would probably 1362 * die with a core dump. 1363 * Thus, we are force our way in by taking out two instructions 1364 * and insert an eternal loop instead, in expectance of the SIGSTOP 1365 * generated by out PTRACE_ATTACH. 1366 * Of cause, if we evaporate ourselves in the middle of all this... 1367 */ 1368 errno = 0; 1369 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOPA); 1370 if(errno) { 1371 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1372 return -1; 1373 } 1374 tcp->flags |= TCB_BPTSET; 1375 1376#else /* !SPARC */ 1377#ifdef IA64 1378 if (ia32) { 1379# define LOOP 0x0000feeb 1380 if (tcp->flags & TCB_BPTSET) { 1381 fprintf(stderr, "PANIC: bpt already set in pid %u\n", 1382 tcp->pid); 1383 return -1; 1384 } 1385 if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0) 1386 return -1; 1387 if (debug) 1388 fprintf(stderr, "[%d] setting bpt at %lx\n", 1389 tcp->pid, tcp->baddr); 1390 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, 1391 (char *) tcp->baddr, 0); 1392 if (errno) { 1393 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1394 return -1; 1395 } 1396 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 1397 if (errno) { 1398 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1399 return -1; 1400 } 1401 tcp->flags |= TCB_BPTSET; 1402 } else { 1403 /* 1404 * Our strategy here is to replace the bundle that 1405 * contained the clone() syscall with a bundle of the 1406 * form: 1407 * 1408 * { 1: br 1b; br 1b; br 1b } 1409 * 1410 * This ensures that the newly forked child will loop 1411 * endlessly until we've got a chance to attach to it. 1412 */ 1413# define LOOP0 0x0000100000000017 1414# define LOOP1 0x4000000000200000 1415 unsigned long addr, ipsr; 1416 pid_t pid; 1417 1418 pid = tcp->pid; 1419 if (upeek(pid, PT_CR_IPSR, &ipsr) < 0) 1420 return -1; 1421 if (upeek(pid, PT_CR_IIP, &addr) < 0) 1422 return -1; 1423 /* store "ri" in low two bits */ 1424 tcp->baddr = addr | ((ipsr >> 41) & 0x3); 1425 1426 errno = 0; 1427 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0, 1428 0); 1429 tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8, 1430 0); 1431 if (errno) { 1432 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1433 return -1; 1434 } 1435 1436 errno = 0; 1437 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0); 1438 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1); 1439 if (errno) { 1440 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1441 return -1; 1442 } 1443 tcp->flags |= TCB_BPTSET; 1444 } 1445#else /* !IA64 */ 1446 1447#if defined (I386) || defined(X86_64) 1448#define LOOP 0x0000feeb 1449#elif defined (M68K) 1450#define LOOP 0x60fe0000 1451#elif defined (ALPHA) 1452#define LOOP 0xc3ffffff 1453#elif defined (POWERPC) 1454#define LOOP 0x48000000 1455#elif defined(ARM) 1456#define LOOP 0xEAFFFFFE 1457#elif defined(MIPS) 1458#define LOOP 0x1000ffff 1459#elif defined(S390) 1460#define LOOP 0xa7f40000 /* BRC 15,0 */ 1461#elif defined(S390X) 1462#define LOOP 0xa7f4000000000000UL /* BRC 15,0 */ 1463#elif defined(HPPA) 1464#define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */ 1465#elif defined(SH) 1466#ifdef __LITTLE_ENDIAN__ 1467#define LOOP 0x0000affe 1468#else 1469#define LOOP 0xfeaf0000 1470#endif 1471#else 1472#error unknown architecture 1473#endif 1474 1475 if (tcp->flags & TCB_BPTSET) { 1476 fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid); 1477 return -1; 1478 } 1479#if defined (I386) 1480 if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0) 1481 return -1; 1482#elif defined (X86_64) 1483 if (upeek(tcp->pid, 8*RIP, &tcp->baddr) < 0) 1484 return -1; 1485#elif defined (M68K) 1486 if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0) 1487 return -1; 1488#elif defined (ALPHA) 1489 return -1; 1490#elif defined (ARM) 1491 return -1; 1492#elif defined (MIPS) 1493 return -1; /* FIXME: I do not know what i do - Flo */ 1494#elif defined (POWERPC) 1495 if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0) 1496 return -1; 1497#elif defined(S390) || defined(S390X) 1498 if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0) 1499 return -1; 1500#elif defined(HPPA) 1501 if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0) 1502 return -1; 1503 tcp->baddr &= ~0x03; 1504#elif defined(SH) 1505 if (upeek(tcp->pid, 4*REG_PC, &tcp->baddr) < 0) 1506 return -1; 1507#else 1508#error unknown architecture 1509#endif 1510 if (debug) 1511 fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr); 1512 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0); 1513 if (errno) { 1514 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1515 return -1; 1516 } 1517 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 1518 if (errno) { 1519 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1520 return -1; 1521 } 1522 tcp->flags |= TCB_BPTSET; 1523 1524#endif /* !IA64 */ 1525#endif /* SPARC */ 1526#endif /* LINUX */ 1527 1528#ifdef SUNOS4 1529#ifdef SPARC /* This code is slightly sparc specific */ 1530 1531 struct regs regs; 1532#define BPT 0x91d02001 /* ta 1 */ 1533#define LOOP 0x10800000 /* ba 0 */ 1534#define LOOPA 0x30800000 /* ba,a 0 */ 1535#define NOP 0x01000000 1536#if LOOPA 1537 static int loopdeloop[1] = {LOOPA}; 1538#else 1539 static int loopdeloop[2] = {LOOP, NOP}; 1540#endif 1541 1542 if (tcp->flags & TCB_BPTSET) { 1543 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1544 return -1; 1545 } 1546 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1547 perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 1548 return -1; 1549 } 1550 tcp->baddr = regs.r_o7 + 8; 1551 if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 1552 sizeof tcp->inst, (char *)tcp->inst) < 0) { 1553 perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 1554 return -1; 1555 } 1556 1557 /* 1558 * XXX - BRUTAL MODE ON 1559 * We cannot set a real BPT in the child, since it will not be 1560 * traced at the moment it will reach the trap and would probably 1561 * die with a core dump. 1562 * Thus, we are force our way in by taking out two instructions 1563 * and insert an eternal loop in stead, in expectance of the SIGSTOP 1564 * generated by out PTRACE_ATTACH. 1565 * Of cause, if we evaporate ourselves in the middle of all this... 1566 */ 1567 if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 1568 sizeof loopdeloop, (char *) loopdeloop) < 0) { 1569 perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 1570 return -1; 1571 } 1572 tcp->flags |= TCB_BPTSET; 1573 1574#endif /* SPARC */ 1575#endif /* SUNOS4 */ 1576 1577 return 0; 1578} 1579 1580int 1581clearbpt(tcp) 1582struct tcb *tcp; 1583{ 1584 1585#ifdef LINUX 1586#if defined(I386) || defined(X86_64) 1587 long eip; 1588#elif defined(POWERPC) 1589 long pc; 1590#elif defined(M68K) 1591 long pc; 1592#elif defined(ALPHA) 1593 long pc; 1594#elif defined(HPPA) 1595 long iaoq; 1596#elif defined(SH) 1597 long pc; 1598#endif /* architecture */ 1599 1600#ifdef SPARC 1601 /* Again, we borrow the SunOS breakpoint code. */ 1602 if (!(tcp->flags & TCB_BPTSET)) { 1603 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 1604 return -1; 1605 } 1606 errno = 0; 1607 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 1608 if(errno) { 1609 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 1610 return -1; 1611 } 1612 tcp->flags &= ~TCB_BPTSET; 1613#elif defined(IA64) 1614 if (ia32) { 1615 unsigned long addr; 1616 1617 if (debug) 1618 fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 1619 if (!(tcp->flags & TCB_BPTSET)) { 1620 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 1621 return -1; 1622 } 1623 errno = 0; 1624 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 1625 if (errno) { 1626 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 1627 return -1; 1628 } 1629 tcp->flags &= ~TCB_BPTSET; 1630 1631 if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0) 1632 return -1; 1633 if (addr != tcp->baddr) { 1634 /* The breakpoint has not been reached yet. */ 1635 if (debug) 1636 fprintf(stderr, 1637 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 1638 addr, tcp->baddr); 1639 return 0; 1640 } 1641 } else { 1642 unsigned long addr, ipsr; 1643 pid_t pid; 1644 1645 pid = tcp->pid; 1646 1647 if (upeek(pid, PT_CR_IPSR, &ipsr) < 0) 1648 return -1; 1649 if (upeek(pid, PT_CR_IIP, &addr) < 0) 1650 return -1; 1651 1652 /* restore original bundle: */ 1653 errno = 0; 1654 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]); 1655 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]); 1656 if (errno) { 1657 perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)"); 1658 return -1; 1659 } 1660 1661 /* restore original "ri" in ipsr: */ 1662 ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41); 1663 errno = 0; 1664 ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr); 1665 if (errno) { 1666 perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)"); 1667 return -1; 1668 } 1669 1670 tcp->flags &= ~TCB_BPTSET; 1671 1672 if (addr != (tcp->baddr & ~0x3)) { 1673 /* the breakpoint has not been reached yet. */ 1674 if (debug) 1675 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 1676 addr, tcp->baddr); 1677 return 0; 1678 } 1679 } 1680#else /* !IA64 && ! SPARC */ 1681 1682 if (debug) 1683 fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 1684 if (!(tcp->flags & TCB_BPTSET)) { 1685 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 1686 return -1; 1687 } 1688 errno = 0; 1689 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 1690 if (errno) { 1691 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 1692 return -1; 1693 } 1694 tcp->flags &= ~TCB_BPTSET; 1695 1696#ifdef I386 1697 if (upeek(tcp->pid, 4*EIP, &eip) < 0) 1698 return -1; 1699 if (eip != tcp->baddr) { 1700 /* The breakpoint has not been reached yet. */ 1701 if (debug) 1702 fprintf(stderr, 1703 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 1704 eip, tcp->baddr); 1705 return 0; 1706 } 1707#elif defined(X86_64) 1708 if (upeek(tcp->pid, 8*RIP, &eip) < 0) 1709 return -1; 1710 if (eip != tcp->baddr) { 1711 /* The breakpoint has not been reached yet. */ 1712 if (debug) 1713 fprintf(stderr, 1714 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 1715 eip, tcp->baddr); 1716 return 0; 1717 } 1718#elif defined(POWERPC) 1719 if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) 1720 return -1; 1721 if (pc != tcp->baddr) { 1722 /* The breakpoint has not been reached yet. */ 1723 if (debug) 1724 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 1725 pc, tcp->baddr); 1726 return 0; 1727 } 1728#elif defined(M68K) 1729 if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) 1730 return -1; 1731 if (pc != tcp->baddr) { 1732 /* The breakpoint has not been reached yet. */ 1733 if (debug) 1734 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 1735 pc, tcp->baddr); 1736 return 0; 1737 } 1738#elif defined(ALPHA) 1739 if (upeek(tcp->pid, REG_PC, &pc) < 0) 1740 return -1; 1741 if (pc != tcp->baddr) { 1742 /* The breakpoint has not been reached yet. */ 1743 if (debug) 1744 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 1745 pc, tcp->baddr); 1746 return 0; 1747 } 1748#elif defined(HPPA) 1749 if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0) 1750 return -1; 1751 iaoq &= ~0x03; 1752 if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) { 1753 /* The breakpoint has not been reached yet. */ 1754 if (debug) 1755 fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n", 1756 iaoq, tcp->baddr); 1757 return 0; 1758 } 1759 iaoq = tcp->baddr | 3; 1760 /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is 1761 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit 1762 * has no significant effect. 1763 */ 1764 ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq); 1765 ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq); 1766#elif defined(SH) 1767 if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) 1768 return -1; 1769 if (pc != tcp->baddr) { 1770 /* The breakpoint has not been reached yet. */ 1771 if (debug) 1772 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 1773 pc, tcp->baddr); 1774 return 0; 1775 } 1776 1777#endif /* arch */ 1778#endif /* !SPARC && !IA64 */ 1779#endif /* LINUX */ 1780 1781#ifdef SUNOS4 1782#ifdef SPARC 1783 1784#if !LOOPA 1785 struct regs regs; 1786#endif 1787 1788 if (!(tcp->flags & TCB_BPTSET)) { 1789 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 1790 return -1; 1791 } 1792 if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 1793 sizeof tcp->inst, (char *) tcp->inst) < 0) { 1794 perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 1795 return -1; 1796 } 1797 tcp->flags &= ~TCB_BPTSET; 1798 1799#if !LOOPA 1800 /* 1801 * Since we don't have a single instruction breakpoint, we may have 1802 * to adjust the program counter after removing the our `breakpoint'. 1803 */ 1804 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1805 perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 1806 return -1; 1807 } 1808 if ((regs.r_pc < tcp->baddr) || 1809 (regs.r_pc > tcp->baddr + 4)) { 1810 /* The breakpoint has not been reached yet */ 1811 if (debug) 1812 fprintf(stderr, 1813 "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 1814 regs.r_pc, tcp->parent->baddr); 1815 return 0; 1816 } 1817 if (regs.r_pc != tcp->baddr) 1818 if (debug) 1819 fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 1820 regs.r_pc, tcp->baddr); 1821 1822 regs.r_pc = tcp->baddr; 1823 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 1824 perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 1825 return -1; 1826 } 1827#endif /* LOOPA */ 1828#endif /* SPARC */ 1829#endif /* SUNOS4 */ 1830 1831 return 0; 1832} 1833 1834#endif 1835 1836#endif /* !USE_PROCFS */ 1837 1838#ifdef SUNOS4 1839 1840static int 1841getex(pid, hdr) 1842int pid; 1843struct exec *hdr; 1844{ 1845 int n; 1846 1847 for (n = 0; n < sizeof *hdr; n += 4) { 1848 long res; 1849 if (upeek(pid, uoff(u_exdata) + n, &res) < 0) 1850 return -1; 1851 memcpy(((char *) hdr) + n, &res, 4); 1852 } 1853 if (debug) { 1854 fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 1855 hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 1856 fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 1857 hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 1858 } 1859 return 0; 1860} 1861 1862int 1863fixvfork(tcp) 1864struct tcb *tcp; 1865{ 1866 int pid = tcp->pid; 1867 /* 1868 * Change `vfork' in a freshly exec'ed dynamically linked 1869 * executable's (internal) symbol table to plain old `fork' 1870 */ 1871 1872 struct exec hdr; 1873 struct link_dynamic dyn; 1874 struct link_dynamic_2 ld; 1875 char *strtab, *cp; 1876 1877 if (getex(pid, &hdr) < 0) 1878 return -1; 1879 if (!hdr.a_dynamic) 1880 return -1; 1881 1882 if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 1883 fprintf(stderr, "Cannot read DYNAMIC\n"); 1884 return -1; 1885 } 1886 if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 1887 fprintf(stderr, "Cannot read link_dynamic_2\n"); 1888 return -1; 1889 } 1890 if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 1891 fprintf(stderr, "fixvfork: out of memory\n"); 1892 return -1; 1893 } 1894 if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 1895 (int)ld.ld_symb_size, strtab) < 0) 1896 goto err; 1897 1898#if 0 1899 for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 1900 fprintf(stderr, "[symbol: %s]\n", cp); 1901 cp += strlen(cp)+1; 1902 } 1903 return 0; 1904#endif 1905 for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 1906 if (strcmp(cp, "_vfork") == 0) { 1907 if (debug) 1908 fprintf(stderr, "fixvfork: FOUND _vfork\n"); 1909 strcpy(cp, "_fork"); 1910 break; 1911 } 1912 cp += strlen(cp)+1; 1913 } 1914 if (cp < strtab + ld.ld_symb_size) 1915 /* 1916 * Write entire symbol table back to avoid 1917 * memory alignment bugs in ptrace 1918 */ 1919 if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 1920 (int)ld.ld_symb_size, strtab) < 0) 1921 goto err; 1922 1923 free(strtab); 1924 return 0; 1925 1926err: 1927 free(strtab); 1928 return -1; 1929} 1930 1931#endif /* SUNOS4 */ 1932