util.c revision 3bb7cd6660032e97f76e8f62efd3540dbba97656
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# ifdef HAVE_STRUCT_IA64_FPREG 67# define ia64_fpreg XXX_ia64_fpreg 68# endif 69# ifdef HAVE_STRUCT_PT_ALL_USER_REGS 70# define pt_all_user_regs XXX_pt_all_user_regs 71# endif 72#include <linux/ptrace.h> 73# undef ia64_fpreg 74# undef pt_all_user_regs 75#endif 76 77#ifdef SUNOS4_KERNEL_ARCH_KLUDGE 78#include <sys/utsname.h> 79#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 80 81#if defined(LINUXSPARC) 82 83# define fpq kernel_fpq 84# define fq kernel_fq 85# define fpu kernel_fpu 86# include <asm/reg.h> 87# undef fpq 88# undef fq 89# undef fpu 90 91#if defined (SPARC64) 92# define r_pc r_tpc 93# undef PTRACE_GETREGS 94# define PTRACE_GETREGS PTRACE_GETREGS64 95# undef PTRACE_SETREGS 96# define PTRACE_SETREGS PTRACE_SETREGS64 97#endif /* SPARC64 */ 98 99#if !defined(__GLIBC__) 100 101#include <linux/unistd.h> 102 103#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\ 104 type5,arg5,syscall) \ 105type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ 106{ \ 107 long __res; \ 108\ 109__asm__ volatile ("or %%g0, %1, %%o0\n\t" \ 110 "or %%g0, %2, %%o1\n\t" \ 111 "or %%g0, %3, %%o2\n\t" \ 112 "or %%g0, %4, %%o3\n\t" \ 113 "or %%g0, %5, %%o4\n\t" \ 114 "or %%g0, %6, %%g1\n\t" \ 115#if defined (SPARC64) 116 "t 0x6d\n\t" \ 117#else 118 "t 0x10\n\t" \ 119#endif 120 "bcc 1f\n\t" \ 121 "or %%g0, %%o0, %0\n\t" \ 122 "sub %%g0, %%o0, %0\n\t" \ 123 "1:\n\t" \ 124 : "=r" (__res) \ 125 : "0" ((long)(arg1)),"1" ((long)(arg2)), \ 126 "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \ 127 "i" (__NR_##syscall) \ 128 : "g1", "o0", "o1", "o2", "o3", "o4"); \ 129if (__res>=0) \ 130 return (type) __res; \ 131errno = -__res; \ 132return -1; \ 133} 134 135static _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace) 136 137#define _ptrace 138 139#endif 140 141#endif 142 143/* macros */ 144#ifndef MAX 145#define MAX(a,b) (((a) > (b)) ? (a) : (b)) 146#endif 147#ifndef MIN 148#define MIN(a,b) (((a) < (b)) ? (a) : (b)) 149#endif 150 151#if 0 152void 153tv_tv(tv, a, b) 154struct timeval *tv; 155int a; 156int b; 157{ 158 tv->tv_sec = a; 159 tv->tv_usec = b; 160} 161#endif 162 163int 164tv_nz(a) 165struct timeval *a; 166{ 167 return a->tv_sec || a->tv_usec; 168} 169 170int 171tv_cmp(a, b) 172struct timeval *a, *b; 173{ 174 if (a->tv_sec < b->tv_sec 175 || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) 176 return -1; 177 if (a->tv_sec > b->tv_sec 178 || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec)) 179 return 1; 180 return 0; 181} 182 183double 184tv_float(tv) 185struct timeval *tv; 186{ 187 return tv->tv_sec + tv->tv_usec/1000000.0; 188} 189 190void 191tv_add(tv, a, b) 192struct timeval *tv, *a, *b; 193{ 194 tv->tv_sec = a->tv_sec + b->tv_sec; 195 tv->tv_usec = a->tv_usec + b->tv_usec; 196 if (tv->tv_usec >= 1000000) { 197 tv->tv_sec++; 198 tv->tv_usec -= 1000000; 199 } 200} 201 202void 203tv_sub(tv, a, b) 204struct timeval *tv, *a, *b; 205{ 206 tv->tv_sec = a->tv_sec - b->tv_sec; 207 tv->tv_usec = a->tv_usec - b->tv_usec; 208 if (((long) tv->tv_usec) < 0) { 209 tv->tv_sec--; 210 tv->tv_usec += 1000000; 211 } 212} 213 214void 215tv_div(tv, a, n) 216struct timeval *tv, *a; 217int n; 218{ 219 tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n; 220 tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000; 221 tv->tv_usec %= 1000000; 222} 223 224void 225tv_mul(tv, a, n) 226struct timeval *tv, *a; 227int n; 228{ 229 tv->tv_usec = a->tv_usec * n; 230 tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000; 231 tv->tv_usec %= 1000000; 232} 233 234const char * 235xlookup(const struct xlat *xlat, int val) 236{ 237 for (; xlat->str != NULL; xlat++) 238 if (xlat->val == val) 239 return xlat->str; 240 return NULL; 241} 242 243/* 244 * Generic ptrace wrapper which tracks ESRCH errors 245 * by setting tcp->ptrace_errno to ESRCH. 246 * 247 * We assume that ESRCH indicates likely process death (SIGKILL?), 248 * modulo bugs where process somehow ended up not stopped. 249 * Unfortunately kernel uses ESRCH for that case too. Oh well. 250 * 251 * Currently used by upeek() only. 252 * TODO: use this in all other ptrace() calls while decoding. 253 */ 254long 255do_ptrace(int request, struct tcb *tcp, void *addr, void *data) 256{ 257 long l; 258 259 errno = 0; 260 l = ptrace(request, tcp->pid, addr, data); 261 /* Non-ESRCH errors might be our invalid reg/mem accesses, 262 * we do not record them. */ 263 if (errno == ESRCH) 264 tcp->ptrace_errno = ESRCH; 265 return l; 266} 267 268/* 269 * Used when we want to unblock stopped traced process. 270 * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL. 271 * Returns 0 on success or if error was ESRCH 272 * (presumably process was killed while we talk to it). 273 * Otherwise prints error message and returns -1. 274 */ 275int 276ptrace_restart(int op, struct tcb *tcp, int sig) 277{ 278 int err; 279 const char *msg; 280 281 errno = 0; 282 ptrace(op, tcp->pid, (void *) 1, (void *) (long) sig); 283 err = errno; 284 if (!err || err == ESRCH) 285 return 0; 286 287 tcp->ptrace_errno = err; 288 msg = "SYSCALL"; 289 if (op == PTRACE_CONT) 290 msg = "CONT"; 291 if (op == PTRACE_DETACH) 292 msg = "DETACH"; 293 fprintf(stderr, "strace: ptrace(PTRACE_%s,1,%d): %s\n", 294 msg, sig, strerror(err)); 295 return -1; 296} 297 298/* 299 * Print entry in struct xlat table, if there. 300 */ 301void 302printxval(const struct xlat *xlat, int val, const char *dflt) 303{ 304 const char *str = xlookup(xlat, val); 305 306 if (str) 307 tprintf("%s", str); 308 else 309 tprintf("%#x /* %s */", val, dflt); 310} 311 312/* 313 * Interpret `xlat' as an array of flags 314 * print the entries whose bits are on in `flags' 315 * return # of flags printed. 316 */ 317int 318addflags(xlat, flags) 319const struct xlat *xlat; 320int flags; 321{ 322 int n; 323 324 for (n = 0; xlat->str; xlat++) { 325 if (xlat->val && (flags & xlat->val) == xlat->val) { 326 tprintf("|%s", xlat->str); 327 flags &= ~xlat->val; 328 n++; 329 } 330 } 331 if (flags) { 332 tprintf("|%#x", flags); 333 n++; 334 } 335 return n; 336} 337 338/* 339 * Interpret `xlat' as an array of flags/ 340 * Print to static string the entries whose bits are on in `flags' 341 * Return static string. 342 */ 343const char * 344sprintflags(const char *prefix, const struct xlat *xlat, int flags) 345{ 346 static char outstr[1024]; 347 int found = 0; 348 349 strcpy(outstr, prefix); 350 351 for (; xlat->str; xlat++) { 352 if ((flags & xlat->val) == xlat->val) { 353 if (found) 354 strcat(outstr, "|"); 355 strcat(outstr, xlat->str); 356 flags &= ~xlat->val; 357 found = 1; 358 } 359 } 360 if (flags) { 361 if (found) 362 strcat(outstr, "|"); 363 sprintf(outstr + strlen(outstr), "%#x", flags); 364 } 365 366 return outstr; 367} 368 369int 370printflags(xlat, flags, dflt) 371const struct xlat *xlat; 372int flags; 373const char *dflt; 374{ 375 int n; 376 char *sep; 377 378 if (flags == 0 && xlat->val == 0) { 379 tprintf("%s", xlat->str); 380 return 1; 381 } 382 383 sep = ""; 384 for (n = 0; xlat->str; xlat++) { 385 if (xlat->val && (flags & xlat->val) == xlat->val) { 386 tprintf("%s%s", sep, xlat->str); 387 flags &= ~xlat->val; 388 sep = "|"; 389 n++; 390 } 391 } 392 393 if (n) { 394 if (flags) { 395 tprintf("%s%#x", sep, flags); 396 n++; 397 } 398 } else { 399 if (flags) { 400 tprintf("%#x", flags); 401 if (dflt) 402 tprintf(" /* %s */", dflt); 403 } else { 404 if (dflt) 405 tprintf("0"); 406 } 407 } 408 409 return n; 410} 411 412void 413printnum(tcp, addr, fmt) 414struct tcb *tcp; 415long addr; 416char *fmt; 417{ 418 long num; 419 420 if (!addr) { 421 tprintf("NULL"); 422 return; 423 } 424 if (umove(tcp, addr, &num) < 0) { 425 tprintf("%#lx", addr); 426 return; 427 } 428 tprintf("["); 429 tprintf(fmt, num); 430 tprintf("]"); 431} 432 433void 434printnum_int(tcp, addr, fmt) 435struct tcb *tcp; 436long addr; 437char *fmt; 438{ 439 int num; 440 441 if (!addr) { 442 tprintf("NULL"); 443 return; 444 } 445 if (umove(tcp, addr, &num) < 0) { 446 tprintf("%#lx", addr); 447 return; 448 } 449 tprintf("["); 450 tprintf(fmt, num); 451 tprintf("]"); 452} 453 454void 455printuid(text, uid) 456const char *text; 457unsigned long uid; 458{ 459 tprintf("%s", text); 460 tprintf((uid == -1) ? "%ld" : "%lu", uid); 461} 462 463static char path[MAXPATHLEN + 1]; 464 465/* 466 * Quote string `instr' of length `size' 467 * Write up to (3 + `size' * 4) bytes to `outstr' buffer. 468 * If `len' < 0, treat `instr' as a NUL-terminated string 469 * and quote at most (`size' - 1) bytes. 470 */ 471static int 472string_quote(const char *instr, char *outstr, int len, int size) 473{ 474 const unsigned char *ustr = (const unsigned char *) instr; 475 char *s = outstr; 476 int usehex = 0, c, i; 477 478 if (xflag > 1) 479 usehex = 1; 480 else if (xflag) { 481 /* Check for presence of symbol which require 482 to hex-quote the whole string. */ 483 for (i = 0; i < size; ++i) { 484 c = ustr[i]; 485 /* Check for NUL-terminated string. */ 486 if (len < 0) { 487 if (c == '\0') 488 break; 489 /* Quote at most size - 1 bytes. */ 490 if (i == size - 1) 491 continue; 492 } 493 if (!isprint(c) && !isspace(c)) { 494 usehex = 1; 495 break; 496 } 497 } 498 } 499 500 *s++ = '\"'; 501 502 if (usehex) { 503 /* Hex-quote the whole string. */ 504 for (i = 0; i < size; ++i) { 505 c = ustr[i]; 506 /* Check for NUL-terminated string. */ 507 if (len < 0) { 508 if (c == '\0') 509 break; 510 /* Quote at most size - 1 bytes. */ 511 if (i == size - 1) 512 continue; 513 } 514 sprintf(s, "\\x%02x", c); 515 s += 4; 516 } 517 } else { 518 for (i = 0; i < size; ++i) { 519 c = ustr[i]; 520 /* Check for NUL-terminated string. */ 521 if (len < 0) { 522 if (c == '\0') 523 break; 524 /* Quote at most size - 1 bytes. */ 525 if (i == size - 1) 526 continue; 527 } 528 switch (c) { 529 case '\"': case '\\': 530 *s++ = '\\'; 531 *s++ = c; 532 break; 533 case '\f': 534 *s++ = '\\'; 535 *s++ = 'f'; 536 break; 537 case '\n': 538 *s++ = '\\'; 539 *s++ = 'n'; 540 break; 541 case '\r': 542 *s++ = '\\'; 543 *s++ = 'r'; 544 break; 545 case '\t': 546 *s++ = '\\'; 547 *s++ = 't'; 548 break; 549 case '\v': 550 *s++ = '\\'; 551 *s++ = 'v'; 552 break; 553 default: 554 if (isprint(c)) 555 *s++ = c; 556 else if (i + 1 < size 557 && isdigit(ustr[i + 1])) { 558 sprintf(s, "\\%03o", c); 559 s += 4; 560 } else { 561 sprintf(s, "\\%o", c); 562 s += strlen(s); 563 } 564 break; 565 } 566 } 567 } 568 569 *s++ = '\"'; 570 *s = '\0'; 571 572 /* Return nonzero if the string was unterminated. */ 573 return i == size; 574} 575 576/* 577 * Print path string specified by address `addr' and length `n'. 578 * If path length exceeds `n', append `...' to the output. 579 */ 580void 581printpathn(struct tcb *tcp, long addr, int n) 582{ 583 if (!addr) { 584 tprintf("NULL"); 585 return; 586 } 587 588 /* Cap path length to the path buffer size, 589 and NUL-terminate the buffer. */ 590 if (n > sizeof path - 1) 591 n = sizeof path - 1; 592 path[n] = '\0'; 593 594 /* Fetch one byte more to find out whether path length > n. */ 595 if (umovestr(tcp, addr, n + 1, path) < 0) 596 tprintf("%#lx", addr); 597 else { 598 static char outstr[4*(sizeof path - 1) + sizeof "\"...\""]; 599 int trunc = (path[n] != '\0'); 600 601 if (trunc) 602 path[n] = '\0'; 603 (void) string_quote(path, outstr, -1, n + 1); 604 if (trunc) 605 strcat(outstr, "..."); 606 tprintf("%s", outstr); 607 } 608} 609 610void 611printpath(struct tcb *tcp, long addr) 612{ 613 printpathn(tcp, addr, sizeof path - 1); 614} 615 616/* 617 * Print string specified by address `addr' and length `len'. 618 * If `len' < 0, treat the string as a NUL-terminated string. 619 * If string length exceeds `max_strlen', append `...' to the output. 620 */ 621void 622printstr(struct tcb *tcp, long addr, int len) 623{ 624 static char *str = NULL; 625 static char *outstr; 626 int size; 627 628 if (!addr) { 629 tprintf("NULL"); 630 return; 631 } 632 /* Allocate static buffers if they are not allocated yet. */ 633 if (!str) 634 str = malloc(max_strlen + 1); 635 if (!outstr) 636 outstr = malloc(4 * max_strlen + sizeof "\"...\""); 637 if (!str || !outstr) { 638 fprintf(stderr, "out of memory\n"); 639 tprintf("%#lx", addr); 640 return; 641 } 642 643 if (len < 0) { 644 /* 645 * Treat as a NUL-terminated string: fetch one byte more 646 * because string_quote() quotes one byte less. 647 */ 648 size = max_strlen + 1; 649 str[max_strlen] = '\0'; 650 if (umovestr(tcp, addr, size, str) < 0) { 651 tprintf("%#lx", addr); 652 return; 653 } 654 } 655 else { 656 size = MIN(len, max_strlen); 657 if (umoven(tcp, addr, size, str) < 0) { 658 tprintf("%#lx", addr); 659 return; 660 } 661 } 662 663 if (string_quote(str, outstr, len, size) && 664 (len < 0 || len > max_strlen)) 665 strcat(outstr, "..."); 666 667 tprintf("%s", outstr); 668} 669 670#if HAVE_SYS_UIO_H 671void 672dumpiov(tcp, len, addr) 673struct tcb * tcp; 674int len; 675long addr; 676{ 677#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 678 union { 679 struct { u_int32_t base; u_int32_t len; } *iov32; 680 struct { u_int64_t base; u_int64_t len; } *iov64; 681 } iovu; 682#define iov iovu.iov64 683#define sizeof_iov \ 684 (personality_wordsize[current_personality] == 4 \ 685 ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64)) 686#define iov_iov_base(i) \ 687 (personality_wordsize[current_personality] == 4 \ 688 ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base) 689#define iov_iov_len(i) \ 690 (personality_wordsize[current_personality] == 4 \ 691 ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len) 692#else 693 struct iovec *iov; 694#define sizeof_iov sizeof(*iov) 695#define iov_iov_base(i) iov[i].iov_base 696#define iov_iov_len(i) iov[i].iov_len 697#endif 698 int i; 699 unsigned long size; 700 701 size = sizeof_iov * (unsigned long) len; 702 if (size / sizeof_iov != len 703 || (iov = malloc(size)) == NULL) { 704 fprintf(stderr, "out of memory\n"); 705 return; 706 } 707 if (umoven(tcp, addr, size, (char *) iov) >= 0) { 708 for (i = 0; i < len; i++) { 709 /* include the buffer number to make it easy to 710 * match up the trace with the source */ 711 tprintf(" * %lu bytes in buffer %d\n", 712 (unsigned long)iov_iov_len(i), i); 713 dumpstr(tcp, (long) iov_iov_base(i), 714 iov_iov_len(i)); 715 } 716 } 717 free((char *) iov); 718#undef sizeof_iov 719#undef iov_iov_base 720#undef iov_iov_len 721#undef iov 722} 723#endif 724 725void 726dumpstr(tcp, addr, len) 727struct tcb *tcp; 728long addr; 729int len; 730{ 731 static int strsize = -1; 732 static unsigned char *str; 733 static char outstr[80]; 734 char *s; 735 int i, j; 736 737 if (strsize < len) { 738 if (str) 739 free(str); 740 if ((str = malloc(len)) == NULL) { 741 fprintf(stderr, "out of memory\n"); 742 return; 743 } 744 strsize = len; 745 } 746 747 if (umoven(tcp, addr, len, (char *) str) < 0) 748 return; 749 750 for (i = 0; i < len; i += 16) { 751 s = outstr; 752 sprintf(s, " | %05x ", i); 753 s += 9; 754 for (j = 0; j < 16; j++) { 755 if (j == 8) 756 *s++ = ' '; 757 if (i + j < len) { 758 sprintf(s, " %02x", str[i + j]); 759 s += 3; 760 } 761 else { 762 *s++ = ' '; *s++ = ' '; *s++ = ' '; 763 } 764 } 765 *s++ = ' '; *s++ = ' '; 766 for (j = 0; j < 16; j++) { 767 if (j == 8) 768 *s++ = ' '; 769 if (i + j < len) { 770 if (isprint(str[i + j])) 771 *s++ = str[i + j]; 772 else 773 *s++ = '.'; 774 } 775 else 776 *s++ = ' '; 777 } 778 tprintf("%s |\n", outstr); 779 } 780} 781 782#define PAGMASK (~(PAGSIZ - 1)) 783/* 784 * move `len' bytes of data from process `pid' 785 * at address `addr' to our space at `laddr' 786 */ 787int 788umoven(struct tcb *tcp, long addr, int len, char *laddr) 789{ 790#ifdef LINUX 791 int pid = tcp->pid; 792 int n, m; 793 int started = 0; 794 union { 795 long val; 796 char x[sizeof(long)]; 797 } u; 798 799 if (addr & (sizeof(long) - 1)) { 800 /* addr not a multiple of sizeof(long) */ 801 n = addr - (addr & -sizeof(long)); /* residue */ 802 addr &= -sizeof(long); /* residue */ 803 errno = 0; 804 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 805 if (errno) { 806 if (started && (errno==EPERM || errno==EIO)) { 807 /* Ran into 'end of memory' - stupid "printpath" */ 808 return 0; 809 } 810 /* But if not started, we had a bogus address. */ 811 if (addr != 0 && errno != EIO && errno != ESRCH) 812 perror("ptrace: umoven"); 813 return -1; 814 } 815 started = 1; 816 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 817 addr += sizeof(long), laddr += m, len -= m; 818 } 819 while (len) { 820 errno = 0; 821 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 822 if (errno) { 823 if (started && (errno==EPERM || errno==EIO)) { 824 /* Ran into 'end of memory' - stupid "printpath" */ 825 return 0; 826 } 827 if (addr != 0 && errno != EIO && errno != ESRCH) 828 perror("ptrace: umoven"); 829 return -1; 830 } 831 started = 1; 832 memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 833 addr += sizeof(long), laddr += m, len -= m; 834 } 835#endif /* LINUX */ 836 837#ifdef SUNOS4 838 int pid = tcp->pid; 839#if 0 840 int n, m; 841 union { 842 long val; 843 char x[sizeof(long)]; 844 } u; 845 846 if (addr & (sizeof(long) - 1)) { 847 /* addr not a multiple of sizeof(long) */ 848 n = addr - (addr & -sizeof(long)); /* residue */ 849 addr &= -sizeof(long); /* residue */ 850 errno = 0; 851 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 852 if (errno) { 853 if (errno != ESRCH) 854 perror("umoven"); 855 return -1; 856 } 857 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len)); 858 addr += sizeof(long), laddr += m, len -= m; 859 } 860 while (len) { 861 errno = 0; 862 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0); 863 if (errno) { 864 if (errno != ESRCH) 865 perror("umoven"); 866 return -1; 867 } 868 memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 869 addr += sizeof(long), laddr += m, len -= m; 870 } 871#else /* !oldway */ 872 int n; 873 874 while (len) { 875 n = MIN(len, PAGSIZ); 876 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 877 if (ptrace(PTRACE_READDATA, pid, 878 (char *) addr, len, laddr) < 0) { 879 if (errno != ESRCH) { 880 perror("umoven: ptrace(PTRACE_READDATA, ...)"); 881 abort(); 882 } 883 return -1; 884 } 885 len -= n; 886 addr += n; 887 laddr += n; 888 } 889#endif /* !oldway */ 890#endif /* SUNOS4 */ 891 892#ifdef USE_PROCFS 893#ifdef HAVE_MP_PROCFS 894 int fd = tcp->pfd_as; 895#else 896 int fd = tcp->pfd; 897#endif 898 lseek(fd, addr, SEEK_SET); 899 if (read(fd, laddr, len) == -1) 900 return -1; 901#endif /* USE_PROCFS */ 902 903 return 0; 904} 905 906/* 907 * like `umove' but make the additional effort of looking 908 * for a terminating zero byte. 909 */ 910int 911umovestr(struct tcb *tcp, long addr, int len, char *laddr) 912{ 913#ifdef USE_PROCFS 914#ifdef HAVE_MP_PROCFS 915 int fd = tcp->pfd_as; 916#else 917 int fd = tcp->pfd; 918#endif 919 /* Some systems (e.g. FreeBSD) can be upset if we read off the 920 end of valid memory, avoid this by trying to read up 921 to page boundaries. But we don't know what a page is (and 922 getpagesize(2) (if it exists) doesn't necessarily return 923 hardware page size). Assume all pages >= 1024 (a-historical 924 I know) */ 925 926 int page = 1024; /* How to find this? */ 927 int move = page - (addr & (page - 1)); 928 int left = len; 929 930 lseek(fd, addr, SEEK_SET); 931 932 while (left) { 933 if (move > left) move = left; 934 if ((move = read(fd, laddr, move)) <= 0) 935 return left != len ? 0 : -1; 936 if (memchr (laddr, 0, move)) break; 937 left -= move; 938 laddr += move; 939 addr += move; 940 move = page; 941 } 942#else /* !USE_PROCFS */ 943 int started = 0; 944 int pid = tcp->pid; 945 int i, n, m; 946 union { 947 long val; 948 char x[sizeof(long)]; 949 } u; 950 951 if (addr & (sizeof(long) - 1)) { 952 /* addr not a multiple of sizeof(long) */ 953 n = addr - (addr & -sizeof(long)); /* residue */ 954 addr &= -sizeof(long); /* residue */ 955 errno = 0; 956 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 957 if (errno) { 958 if (started && (errno==EPERM || errno==EIO)) { 959 /* Ran into 'end of memory' - stupid "printpath" */ 960 return 0; 961 } 962 if (addr != 0 && errno != EIO && errno != ESRCH) 963 perror("umovestr"); 964 return -1; 965 } 966 started = 1; 967 memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len)); 968 while (n & (sizeof(long) - 1)) 969 if (u.x[n++] == '\0') 970 return 0; 971 addr += sizeof(long), laddr += m, len -= m; 972 } 973 while (len) { 974 errno = 0; 975 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0); 976 if (errno) { 977 if (started && (errno==EPERM || errno==EIO)) { 978 /* Ran into 'end of memory' - stupid "printpath" */ 979 return 0; 980 } 981 if (addr != 0 && errno != EIO && errno != ESRCH) 982 perror("umovestr"); 983 return -1; 984 } 985 started = 1; 986 memcpy(laddr, u.x, m = MIN(sizeof(long), len)); 987 for (i = 0; i < sizeof(long); i++) 988 if (u.x[i] == '\0') 989 return 0; 990 991 addr += sizeof(long), laddr += m, len -= m; 992 } 993#endif /* !USE_PROCFS */ 994 return 0; 995} 996 997#ifdef LINUX 998# if !defined (SPARC) && !defined(SPARC64) 999# define PTRACE_WRITETEXT 101 1000# define PTRACE_WRITEDATA 102 1001# endif /* !SPARC && !SPARC64 */ 1002#endif /* LINUX */ 1003 1004#ifdef SUNOS4 1005 1006static int 1007uload(cmd, pid, addr, len, laddr) 1008int cmd; 1009int pid; 1010long addr; 1011int len; 1012char *laddr; 1013{ 1014# if 0 1015 int n; 1016 1017 while (len) { 1018 n = MIN(len, PAGSIZ); 1019 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr); 1020 if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) { 1021 perror("uload: ptrace(PTRACE_WRITE, ...)"); 1022 return -1; 1023 } 1024 len -= n; 1025 addr += n; 1026 laddr += n; 1027 } 1028# else 1029 int peek, poke; 1030 int n, m; 1031 union { 1032 long val; 1033 char x[sizeof(long)]; 1034 } u; 1035 1036 if (cmd == PTRACE_WRITETEXT) { 1037 peek = PTRACE_PEEKTEXT; 1038 poke = PTRACE_POKETEXT; 1039 } 1040 else { 1041 peek = PTRACE_PEEKDATA; 1042 poke = PTRACE_POKEDATA; 1043 } 1044 if (addr & (sizeof(long) - 1)) { 1045 /* addr not a multiple of sizeof(long) */ 1046 n = addr - (addr & -sizeof(long)); /* residue */ 1047 addr &= -sizeof(long); 1048 errno = 0; 1049 u.val = ptrace(peek, pid, (char *) addr, 0); 1050 if (errno) { 1051 perror("uload: POKE"); 1052 return -1; 1053 } 1054 memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len)); 1055 if (ptrace(poke, pid, (char *)addr, u.val) < 0) { 1056 perror("uload: POKE"); 1057 return -1; 1058 } 1059 addr += sizeof(long), laddr += m, len -= m; 1060 } 1061 while (len) { 1062 if (len < sizeof(long)) 1063 u.val = ptrace(peek, pid, (char *) addr, 0); 1064 memcpy(u.x, laddr, m = MIN(sizeof(long), len)); 1065 if (ptrace(poke, pid, (char *) addr, u.val) < 0) { 1066 perror("uload: POKE"); 1067 return -1; 1068 } 1069 addr += sizeof(long), laddr += m, len -= m; 1070 } 1071# endif 1072 return 0; 1073} 1074 1075int 1076tload(pid, addr, len, laddr) 1077int pid; 1078int addr, len; 1079char *laddr; 1080{ 1081 return uload(PTRACE_WRITETEXT, pid, addr, len, laddr); 1082} 1083 1084int 1085dload(pid, addr, len, laddr) 1086int pid; 1087int addr; 1088int len; 1089char *laddr; 1090{ 1091 return uload(PTRACE_WRITEDATA, pid, addr, len, laddr); 1092} 1093 1094#endif /* SUNOS4 */ 1095 1096#ifndef USE_PROCFS 1097 1098int 1099upeek(tcp, off, res) 1100struct tcb *tcp; 1101long off; 1102long *res; 1103{ 1104 long val; 1105 1106# ifdef SUNOS4_KERNEL_ARCH_KLUDGE 1107 { 1108 static int is_sun4m = -1; 1109 struct utsname name; 1110 1111 /* Round up the usual suspects. */ 1112 if (is_sun4m == -1) { 1113 if (uname(&name) < 0) { 1114 perror("upeek: uname?"); 1115 exit(1); 1116 } 1117 is_sun4m = strcmp(name.machine, "sun4m") == 0; 1118 if (is_sun4m) { 1119 const struct xlat *x; 1120 1121 for (x = struct_user_offsets; x->str; x++) 1122 x->val += 1024; 1123 } 1124 } 1125 if (is_sun4m) 1126 off += 1024; 1127 } 1128# endif /* SUNOS4_KERNEL_ARCH_KLUDGE */ 1129 errno = 0; 1130 val = do_ptrace(PTRACE_PEEKUSER, tcp, (char *) off, 0); 1131 if (val == -1 && errno) { 1132 if (errno != ESRCH) { 1133 char buf[60]; 1134 sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)", tcp->pid, off); 1135 perror(buf); 1136 } 1137 return -1; 1138 } 1139 *res = val; 1140 return 0; 1141} 1142 1143#endif /* !USE_PROCFS */ 1144 1145#if 0 1146long 1147getpc(tcp) 1148struct tcb *tcp; 1149{ 1150 1151#ifdef LINUX 1152 long pc; 1153# if defined(I386) 1154 if (upeek(tcp, 4*EIP, &pc) < 0) 1155 return -1; 1156# elif defined(X86_64) 1157 if (upeek(tcp, 8*RIP, &pc) < 0) 1158 return -1; 1159# elif defined(IA64) 1160 if (upeek(tcp, PT_B0, &pc) < 0) 1161 return -1; 1162# elif defined(ARM) 1163 if (upeek(tcp, 4*15, &pc) < 0) 1164 return -1; 1165# elif defined(BFIN) 1166 if (upeek(tcp, REG_PC, &pc) < 0) 1167 return -1; 1168# elif defined(POWERPC) 1169 if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) 1170 return -1; 1171# elif defined(M68K) 1172 if (upeek(tcp, 4*PT_PC, &pc) < 0) 1173 return -1; 1174# elif defined(ALPHA) 1175 if (upeek(tcp, REG_PC, &pc) < 0) 1176 return -1; 1177# elif defined(MIPS) 1178 if (upeek(tcp, REG_EPC, &pc) < 0) 1179 return -1; 1180# elif defined(SPARC) || defined(SPARC64) 1181 struct regs regs; 1182 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) 1183 return -1; 1184 pc = regs.r_pc; 1185# elif defined(S390) || defined(S390X) 1186 if(upeek(tcp,PT_PSWADDR,&pc) < 0) 1187 return -1; 1188# elif defined(HPPA) 1189 if(upeek(tcp,PT_IAOQ0,&pc) < 0) 1190 return -1; 1191# elif defined(SH) 1192 if (upeek(tcp, 4*REG_PC ,&pc) < 0) 1193 return -1; 1194# elif defined(SH64) 1195 if (upeek(tcp, REG_PC ,&pc) < 0) 1196 return -1; 1197# endif 1198 return pc; 1199#endif /* LINUX */ 1200 1201#ifdef SUNOS4 1202 /* 1203 * Return current program counter for `pid' 1204 * Assumes PC is never 0xffffffff 1205 */ 1206 struct regs regs; 1207 1208 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 1209 perror("getpc: ptrace(PTRACE_GETREGS, ...)"); 1210 return -1; 1211 } 1212 return regs.r_pc; 1213#endif /* SUNOS4 */ 1214 1215#ifdef SVR4 1216 /* XXX */ 1217 return 0; 1218#endif /* SVR4 */ 1219 1220#ifdef FREEBSD 1221 struct reg regs; 1222 pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1223 return regs.r_eip; 1224#endif /* FREEBSD */ 1225} 1226#endif /* 0 */ 1227 1228void 1229printcall(tcp) 1230struct tcb *tcp; 1231{ 1232#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \ 1233 sizeof(long) == 8 ? "[????????????????] " : \ 1234 NULL /* crash */) 1235 1236#ifdef LINUX 1237# ifdef I386 1238 long eip; 1239 1240 if (upeek(tcp, 4*EIP, &eip) < 0) { 1241 PRINTBADPC; 1242 return; 1243 } 1244 tprintf("[%08lx] ", eip); 1245 1246# elif defined(S390) || defined(S390X) 1247 long psw; 1248 if(upeek(tcp,PT_PSWADDR,&psw) < 0) { 1249 PRINTBADPC; 1250 return; 1251 } 1252# ifdef S390 1253 tprintf("[%08lx] ", psw); 1254# elif S390X 1255 tprintf("[%16lx] ", psw); 1256# endif 1257 1258# elif defined(X86_64) 1259 long rip; 1260 1261 if (upeek(tcp, 8*RIP, &rip) < 0) { 1262 PRINTBADPC; 1263 return; 1264 } 1265 tprintf("[%16lx] ", rip); 1266# elif defined(IA64) 1267 long ip; 1268 1269 if (upeek(tcp, PT_B0, &ip) < 0) { 1270 PRINTBADPC; 1271 return; 1272 } 1273 tprintf("[%08lx] ", ip); 1274# elif defined(POWERPC) 1275 long pc; 1276 1277 if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) { 1278 tprintf ("[????????] "); 1279 return; 1280 } 1281 tprintf("[%08lx] ", pc); 1282# elif defined(M68K) 1283 long pc; 1284 1285 if (upeek(tcp, 4*PT_PC, &pc) < 0) { 1286 tprintf ("[????????] "); 1287 return; 1288 } 1289 tprintf("[%08lx] ", pc); 1290# elif defined(ALPHA) 1291 long pc; 1292 1293 if (upeek(tcp, REG_PC, &pc) < 0) { 1294 tprintf ("[????????????????] "); 1295 return; 1296 } 1297 tprintf("[%08lx] ", pc); 1298# elif defined(SPARC) || defined(SPARC64) 1299 struct regs regs; 1300 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) { 1301 PRINTBADPC; 1302 return; 1303 } 1304 tprintf("[%08lx] ", regs.r_pc); 1305# elif defined(HPPA) 1306 long pc; 1307 1308 if(upeek(tcp,PT_IAOQ0,&pc) < 0) { 1309 tprintf ("[????????] "); 1310 return; 1311 } 1312 tprintf("[%08lx] ", pc); 1313# elif defined(MIPS) 1314 long pc; 1315 1316 if (upeek(tcp, REG_EPC, &pc) < 0) { 1317 tprintf ("[????????] "); 1318 return; 1319 } 1320 tprintf("[%08lx] ", pc); 1321# elif defined(SH) 1322 long pc; 1323 1324 if (upeek(tcp, 4*REG_PC, &pc) < 0) { 1325 tprintf ("[????????] "); 1326 return; 1327 } 1328 tprintf("[%08lx] ", pc); 1329# elif defined(SH64) 1330 long pc; 1331 1332 if (upeek(tcp, REG_PC, &pc) < 0) { 1333 tprintf ("[????????????????] "); 1334 return; 1335 } 1336 tprintf("[%08lx] ", pc); 1337# elif defined(ARM) 1338 long pc; 1339 1340 if (upeek(tcp, 4*15, &pc) < 0) { 1341 PRINTBADPC; 1342 return; 1343 } 1344 tprintf("[%08lx] ", pc); 1345# elif defined(BFIN) 1346 long pc; 1347 1348 if (upeek(tcp, PT_PC, &pc) < 0) { 1349 PRINTBADPC; 1350 return; 1351 } 1352 tprintf("[%08lx] ", pc); 1353# endif /* architecture */ 1354#endif /* LINUX */ 1355 1356#ifdef SUNOS4 1357 struct regs regs; 1358 1359 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) { 1360 perror("printcall: ptrace(PTRACE_GETREGS, ...)"); 1361 PRINTBADPC; 1362 return; 1363 } 1364 tprintf("[%08x] ", regs.r_o7); 1365#endif /* SUNOS4 */ 1366 1367#ifdef SVR4 1368 /* XXX */ 1369 PRINTBADPC; 1370#endif 1371 1372#ifdef FREEBSD 1373 struct reg regs; 1374 pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 1375 tprintf("[%08x] ", regs.r_eip); 1376#endif /* FREEBSD */ 1377} 1378 1379 1380/* 1381 * These #if's are huge, please indent them correctly. 1382 * It's easy to get confused otherwise. 1383 */ 1384#ifndef USE_PROCFS 1385 1386# if defined LINUX 1387 1388# include "syscall.h" 1389 1390# include <sys/syscall.h> 1391# ifndef CLONE_PTRACE 1392# define CLONE_PTRACE 0x00002000 1393# endif 1394# ifndef CLONE_VFORK 1395# define CLONE_VFORK 0x00004000 1396# endif 1397# ifndef CLONE_VM 1398# define CLONE_VM 0x00000100 1399# endif 1400# ifndef CLONE_STOPPED 1401# define CLONE_STOPPED 0x02000000 1402# endif 1403 1404# ifdef IA64 1405 1406/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32 1407 subsystem has them for x86... */ 1408# define SYS_fork 2 1409# define SYS_vfork 190 1410 1411typedef unsigned long *arg_setup_state; 1412 1413static int 1414arg_setup(struct tcb *tcp, arg_setup_state *state) 1415{ 1416 unsigned long cfm, sof, sol; 1417 long bsp; 1418 1419 if (ia32) { 1420 /* Satisfy a false GCC warning. */ 1421 *state = NULL; 1422 return 0; 1423 } 1424 1425 if (upeek(tcp, PT_AR_BSP, &bsp) < 0) 1426 return -1; 1427 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0) 1428 return -1; 1429 1430 sof = (cfm >> 0) & 0x7f; 1431 sol = (cfm >> 7) & 0x7f; 1432 bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol); 1433 1434 *state = (unsigned long *) bsp; 1435 return 0; 1436} 1437 1438# define arg_finish_change(tcp, state) 0 1439 1440# ifdef SYS_fork 1441static int 1442get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp) 1443{ 1444 int ret; 1445 1446 if (ia32) 1447 ret = upeek (tcp, PT_R11, valp); 1448 else 1449 ret = umoven (tcp, 1450 (unsigned long) ia64_rse_skip_regs(*state, 0), 1451 sizeof(long), (void *) valp); 1452 return ret; 1453} 1454 1455static int 1456get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp) 1457{ 1458 int ret; 1459 1460 if (ia32) 1461 ret = upeek (tcp, PT_R9, valp); 1462 else 1463 ret = umoven (tcp, 1464 (unsigned long) ia64_rse_skip_regs(*state, 1), 1465 sizeof(long), (void *) valp); 1466 return ret; 1467} 1468# endif 1469 1470static int 1471set_arg0 (struct tcb *tcp, arg_setup_state *state, long val) 1472{ 1473 int req = PTRACE_POKEDATA; 1474 void *ap; 1475 1476 if (ia32) { 1477 ap = (void *) (intptr_t) PT_R11; /* r11 == EBX */ 1478 req = PTRACE_POKEUSER; 1479 } else 1480 ap = ia64_rse_skip_regs(*state, 0); 1481 errno = 0; 1482 ptrace(req, tcp->pid, ap, val); 1483 return errno ? -1 : 0; 1484} 1485 1486static int 1487set_arg1 (struct tcb *tcp, arg_setup_state *state, long val) 1488{ 1489 int req = PTRACE_POKEDATA; 1490 void *ap; 1491 1492 if (ia32) { 1493 ap = (void *) (intptr_t) PT_R9; /* r9 == ECX */ 1494 req = PTRACE_POKEUSER; 1495 } else 1496 ap = ia64_rse_skip_regs(*state, 1); 1497 errno = 0; 1498 ptrace(req, tcp->pid, ap, val); 1499 return errno ? -1 : 0; 1500} 1501 1502/* ia64 does not return the input arguments from functions (and syscalls) 1503 according to ia64 RSE (Register Stack Engine) behavior. */ 1504 1505# define restore_arg0(tcp, state, val) ((void) (state), 0) 1506# define restore_arg1(tcp, state, val) ((void) (state), 0) 1507 1508# elif defined (SPARC) || defined (SPARC64) 1509 1510typedef struct regs arg_setup_state; 1511 1512# define arg_setup(tcp, state) \ 1513 (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0)) 1514# define arg_finish_change(tcp, state) \ 1515 (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0)) 1516 1517# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0) 1518# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0) 1519# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0) 1520# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0) 1521# define restore_arg0(tcp, state, val) 0 1522 1523# else /* other architectures */ 1524 1525# if defined S390 || defined S390X 1526/* Note: this is only true for the `clone' system call, which handles 1527 arguments specially. We could as well say that its first two arguments 1528 are swapped relative to other architectures, but that would just be 1529 another #ifdef in the calls. */ 1530# define arg0_offset PT_GPR3 1531# define arg1_offset PT_ORIGGPR2 1532# define restore_arg0(tcp, state, val) ((void) (state), 0) 1533# define restore_arg1(tcp, state, val) ((void) (state), 0) 1534# define arg0_index 1 1535# define arg1_index 0 1536# elif defined (ALPHA) || defined (MIPS) 1537# define arg0_offset REG_A0 1538# define arg1_offset (REG_A0+1) 1539# elif defined (POWERPC) 1540# define arg0_offset (sizeof(unsigned long)*PT_R3) 1541# define arg1_offset (sizeof(unsigned long)*PT_R4) 1542# define restore_arg0(tcp, state, val) ((void) (state), 0) 1543# elif defined (HPPA) 1544# define arg0_offset PT_GR26 1545# define arg1_offset (PT_GR26-4) 1546# elif defined (X86_64) 1547# define arg0_offset ((long)(8*(current_personality ? RBX : RDI))) 1548# define arg1_offset ((long)(8*(current_personality ? RCX : RSI))) 1549# elif defined (SH) 1550# define arg0_offset (4*(REG_REG0+4)) 1551# define arg1_offset (4*(REG_REG0+5)) 1552# elif defined (SH64) 1553 /* ABI defines arg0 & 1 in r2 & r3 */ 1554# define arg0_offset (REG_OFFSET+16) 1555# define arg1_offset (REG_OFFSET+24) 1556# define restore_arg0(tcp, state, val) 0 1557# else 1558# define arg0_offset 0 1559# define arg1_offset 4 1560# if defined ARM 1561# define restore_arg0(tcp, state, val) 0 1562# endif 1563# endif 1564 1565typedef int arg_setup_state; 1566 1567# define arg_setup(tcp, state) (0) 1568# define arg_finish_change(tcp, state) 0 1569# define get_arg0(tcp, cookie, valp) \ 1570 (upeek ((tcp), arg0_offset, (valp))) 1571# define get_arg1(tcp, cookie, valp) \ 1572 (upeek ((tcp), arg1_offset, (valp))) 1573 1574static int 1575set_arg0 (struct tcb *tcp, void *cookie, long val) 1576{ 1577 return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val); 1578} 1579 1580static int 1581set_arg1 (struct tcb *tcp, void *cookie, long val) 1582{ 1583 return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val); 1584} 1585 1586# endif /* architectures */ 1587 1588# ifndef restore_arg0 1589# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val)) 1590# endif 1591# ifndef restore_arg1 1592# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val)) 1593# endif 1594 1595# ifndef arg0_index 1596# define arg0_index 0 1597# define arg1_index 1 1598# endif 1599 1600int 1601setbpt(struct tcb *tcp) 1602{ 1603 static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone }; 1604 arg_setup_state state; 1605 1606 if (tcp->flags & TCB_BPTSET) { 1607 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1608 return -1; 1609 } 1610 1611 /* 1612 * It's a silly kludge to initialize this with a search at runtime. 1613 * But it's better than maintaining another magic thing in the 1614 * godforsaken tables. 1615 */ 1616 if (clone_scno[current_personality] == 0) { 1617 int i; 1618 for (i = 0; i < nsyscalls; ++i) 1619 if (sysent[i].sys_func == sys_clone) { 1620 clone_scno[current_personality] = i; 1621 break; 1622 } 1623 } 1624 1625 switch (known_scno(tcp)) { 1626# ifdef SYS_vfork 1627 case SYS_vfork: 1628# endif 1629# ifdef SYS_fork 1630 case SYS_fork: 1631# endif 1632# if defined SYS_fork || defined SYS_vfork 1633 if (arg_setup (tcp, &state) < 0 1634 || get_arg0 (tcp, &state, &tcp->inst[0]) < 0 1635 || get_arg1 (tcp, &state, &tcp->inst[1]) < 0 1636 || change_syscall(tcp, clone_scno[current_personality]) < 0 1637 || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 1638 || set_arg1 (tcp, &state, 0) < 0 1639 || arg_finish_change (tcp, &state) < 0) 1640 return -1; 1641 tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD; 1642 tcp->u_arg[arg1_index] = 0; 1643 tcp->flags |= TCB_BPTSET; 1644 return 0; 1645# endif 1646 1647 case SYS_clone: 1648# ifdef SYS_clone2 1649 case SYS_clone2: 1650# endif 1651 /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)' 1652 contrary to x86 SYS_vfork above. Even on x86 we turn the 1653 vfork semantics into plain fork - each application must not 1654 depend on the vfork specifics according to POSIX. We would 1655 hang waiting for the parent resume otherwise. We need to 1656 clear also CLONE_VM but only in the CLONE_VFORK case as 1657 otherwise we would break pthread_create. */ 1658 1659 if ((arg_setup (tcp, &state) < 0 1660 || set_arg0 (tcp, &state, 1661 (tcp->u_arg[arg0_index] | CLONE_PTRACE) 1662 & ~(tcp->u_arg[arg0_index] & CLONE_VFORK 1663 ? CLONE_VFORK | CLONE_VM : 0)) < 0 1664 || arg_finish_change (tcp, &state) < 0)) 1665 return -1; 1666 tcp->flags |= TCB_BPTSET; 1667 tcp->inst[0] = tcp->u_arg[arg0_index]; 1668 tcp->inst[1] = tcp->u_arg[arg1_index]; 1669 return 0; 1670 1671 default: 1672 fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n", 1673 tcp->scno, tcp->pid); 1674 break; 1675 } 1676 1677 return -1; 1678} 1679 1680int 1681clearbpt(tcp) 1682struct tcb *tcp; 1683{ 1684 arg_setup_state state; 1685 if (arg_setup (tcp, &state) < 0 1686 || restore_arg0 (tcp, &state, tcp->inst[0]) < 0 1687 || restore_arg1 (tcp, &state, tcp->inst[1]) < 0 1688 || arg_finish_change (tcp, &state)) 1689 return -1; 1690 tcp->flags &= ~TCB_BPTSET; 1691 return 0; 1692} 1693 1694# else /* !defined LINUX */ 1695 1696int 1697setbpt(tcp) 1698struct tcb *tcp; 1699{ 1700# ifdef LINUX 1701 DEAD CODE HERE? WE ARE IN 'else !defined LINUX' 1702# if defined (SPARC) || defined (SPARC64) 1703 /* We simply use the SunOS breakpoint code. */ 1704 1705 struct regs regs; 1706 unsigned long inst; 1707# define LOOPA 0x30800000 /* ba,a 0 */ 1708 1709 if (tcp->flags & TCB_BPTSET) { 1710 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1711 return -1; 1712 } 1713 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1714 perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 1715 return -1; 1716 } 1717 tcp->baddr = regs.r_o7 + 8; 1718 errno = 0; 1719 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0); 1720 if(errno) { 1721 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1722 return -1; 1723 } 1724 1725 /* 1726 * XXX - BRUTAL MODE ON 1727 * We cannot set a real BPT in the child, since it will not be 1728 * traced at the moment it will reach the trap and would probably 1729 * die with a core dump. 1730 * Thus, we are force our way in by taking out two instructions 1731 * and insert an eternal loop instead, in expectance of the SIGSTOP 1732 * generated by our PTRACE_ATTACH. 1733 * Of cause, if we evaporate ourselves in the middle of all this... 1734 */ 1735 errno = 0; 1736 inst = LOOPA; 1737# if defined (SPARC64) 1738 inst <<= 32; 1739 inst |= (tcp->inst[0] & 0xffffffffUL); 1740# endif 1741 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst); 1742 if(errno) { 1743 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1744 return -1; 1745 } 1746 tcp->flags |= TCB_BPTSET; 1747 1748# else /* !SPARC && !SPARC64 */ 1749# ifdef IA64 1750 if (ia32) { 1751# define LOOP 0x0000feeb 1752 if (tcp->flags & TCB_BPTSET) { 1753 fprintf(stderr, "PANIC: bpt already set in pid %u\n", 1754 tcp->pid); 1755 return -1; 1756 } 1757 if (upeek(tcp, PT_CR_IIP, &tcp->baddr) < 0) 1758 return -1; 1759 if (debug) 1760 fprintf(stderr, "[%d] setting bpt at %lx\n", 1761 tcp->pid, tcp->baddr); 1762 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, 1763 (char *) tcp->baddr, 0); 1764 if (errno) { 1765 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1766 return -1; 1767 } 1768 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 1769 if (errno) { 1770 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1771 return -1; 1772 } 1773 tcp->flags |= TCB_BPTSET; 1774 } else { 1775 /* 1776 * Our strategy here is to replace the bundle that 1777 * contained the clone() syscall with a bundle of the 1778 * form: 1779 * 1780 * { 1: br 1b; br 1b; br 1b } 1781 * 1782 * This ensures that the newly forked child will loop 1783 * endlessly until we've got a chance to attach to it. 1784 */ 1785# define LOOP0 0x0000100000000017 1786# define LOOP1 0x4000000000200000 1787 unsigned long addr, ipsr; 1788 pid_t pid; 1789 1790 pid = tcp->pid; 1791 if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0) 1792 return -1; 1793 if (upeek(tcp, PT_CR_IIP, &addr) < 0) 1794 return -1; 1795 /* store "ri" in low two bits */ 1796 tcp->baddr = addr | ((ipsr >> 41) & 0x3); 1797 1798 errno = 0; 1799 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0, 1800 0); 1801 tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8, 1802 0); 1803 if (errno) { 1804 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1805 return -1; 1806 } 1807 1808 errno = 0; 1809 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0); 1810 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1); 1811 if (errno) { 1812 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1813 return -1; 1814 } 1815 tcp->flags |= TCB_BPTSET; 1816 } 1817# else /* !IA64 */ 1818 1819# if defined (I386) || defined(X86_64) 1820# define LOOP 0x0000feeb 1821# elif defined (M68K) 1822# define LOOP 0x60fe0000 1823# elif defined (ALPHA) 1824# define LOOP 0xc3ffffff 1825# elif defined (POWERPC) 1826# define LOOP 0x48000000 1827# elif defined(ARM) 1828# define LOOP 0xEAFFFFFE 1829# elif defined(MIPS) 1830# define LOOP 0x1000ffff 1831# elif defined(S390) 1832# define LOOP 0xa7f40000 /* BRC 15,0 */ 1833# elif defined(S390X) 1834# define LOOP 0xa7f4000000000000UL /* BRC 15,0 */ 1835# elif defined(HPPA) 1836# define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */ 1837# elif defined(SH) 1838# ifdef __LITTLE_ENDIAN__ 1839# define LOOP 0x0000affe 1840# else 1841# define LOOP 0xfeaf0000 1842# endif 1843# else 1844# error unknown architecture 1845# endif 1846 1847 if (tcp->flags & TCB_BPTSET) { 1848 fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid); 1849 return -1; 1850 } 1851# if defined (I386) 1852 if (upeek(tcp, 4*EIP, &tcp->baddr) < 0) 1853 return -1; 1854# elif defined (X86_64) 1855 if (upeek(tcp, 8*RIP, &tcp->baddr) < 0) 1856 return -1; 1857# elif defined (M68K) 1858 if (upeek(tcp, 4*PT_PC, &tcp->baddr) < 0) 1859 return -1; 1860# elif defined (ALPHA) 1861 return -1; 1862# elif defined (ARM) 1863 return -1; 1864# elif defined (MIPS) 1865 return -1; /* FIXME: I do not know what i do - Flo */ 1866# elif defined (POWERPC) 1867 if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0) 1868 return -1; 1869# elif defined(S390) || defined(S390X) 1870 if (upeek(tcp,PT_PSWADDR, &tcp->baddr) < 0) 1871 return -1; 1872# elif defined(HPPA) 1873 if (upeek(tcp, PT_IAOQ0, &tcp->baddr) < 0) 1874 return -1; 1875 tcp->baddr &= ~0x03; 1876# elif defined(SH) 1877 if (upeek(tcp, 4*REG_PC, &tcp->baddr) < 0) 1878 return -1; 1879# else 1880# error unknown architecture 1881# endif 1882 if (debug) 1883 fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr); 1884 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0); 1885 if (errno) { 1886 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1887 return -1; 1888 } 1889 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 1890 if (errno) { 1891 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1892 return -1; 1893 } 1894 tcp->flags |= TCB_BPTSET; 1895 1896# endif /* !IA64 */ 1897# endif /* !SPARC && !SPARC64 */ 1898# endif /* LINUX */ 1899 1900# ifdef SUNOS4 1901# ifdef SPARC /* This code is slightly sparc specific */ 1902 1903 struct regs regs; 1904# define BPT 0x91d02001 /* ta 1 */ 1905# define LOOP 0x10800000 /* ba 0 */ 1906# define LOOPA 0x30800000 /* ba,a 0 */ 1907# define NOP 0x01000000 1908# if LOOPA 1909 static int loopdeloop[1] = {LOOPA}; 1910# else 1911 static int loopdeloop[2] = {LOOP, NOP}; 1912# endif 1913 1914 if (tcp->flags & TCB_BPTSET) { 1915 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1916 return -1; 1917 } 1918 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1919 perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 1920 return -1; 1921 } 1922 tcp->baddr = regs.r_o7 + 8; 1923 if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 1924 sizeof tcp->inst, (char *)tcp->inst) < 0) { 1925 perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 1926 return -1; 1927 } 1928 1929 /* 1930 * XXX - BRUTAL MODE ON 1931 * We cannot set a real BPT in the child, since it will not be 1932 * traced at the moment it will reach the trap and would probably 1933 * die with a core dump. 1934 * Thus, we are force our way in by taking out two instructions 1935 * and insert an eternal loop in stead, in expectance of the SIGSTOP 1936 * generated by out PTRACE_ATTACH. 1937 * Of cause, if we evaporate ourselves in the middle of all this... 1938 */ 1939 if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 1940 sizeof loopdeloop, (char *) loopdeloop) < 0) { 1941 perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 1942 return -1; 1943 } 1944 tcp->flags |= TCB_BPTSET; 1945 1946# endif /* SPARC */ 1947# endif /* SUNOS4 */ 1948 1949 return 0; 1950} 1951 1952int 1953clearbpt(tcp) 1954struct tcb *tcp; 1955{ 1956 1957# ifdef LINUX 1958 DEAD CODE HERE? WE ARE IN 'else !defined LINUX' 1959# if defined(I386) || defined(X86_64) 1960 long eip; 1961# elif defined(POWERPC) 1962 long pc; 1963# elif defined(M68K) 1964 long pc; 1965# elif defined(ALPHA) 1966 long pc; 1967# elif defined(HPPA) 1968 long iaoq; 1969# elif defined(SH) 1970 long pc; 1971# endif /* architecture */ 1972 1973# if defined (SPARC) || defined (SPARC64) 1974 /* Again, we borrow the SunOS breakpoint code. */ 1975 if (!(tcp->flags & TCB_BPTSET)) { 1976 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 1977 return -1; 1978 } 1979 errno = 0; 1980 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 1981 if(errno) { 1982 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 1983 return -1; 1984 } 1985 tcp->flags &= ~TCB_BPTSET; 1986# elif defined(IA64) 1987 if (ia32) { 1988 unsigned long addr; 1989 1990 if (debug) 1991 fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 1992 if (!(tcp->flags & TCB_BPTSET)) { 1993 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 1994 return -1; 1995 } 1996 errno = 0; 1997 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 1998 if (errno) { 1999 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 2000 return -1; 2001 } 2002 tcp->flags &= ~TCB_BPTSET; 2003 2004 if (upeek(tcp, PT_CR_IIP, &addr) < 0) 2005 return -1; 2006 if (addr != tcp->baddr) { 2007 /* The breakpoint has not been reached yet. */ 2008 if (debug) 2009 fprintf(stderr, 2010 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2011 addr, tcp->baddr); 2012 return 0; 2013 } 2014 } else { 2015 unsigned long addr, ipsr; 2016 pid_t pid; 2017 2018 pid = tcp->pid; 2019 2020 if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0) 2021 return -1; 2022 if (upeek(tcp, PT_CR_IIP, &addr) < 0) 2023 return -1; 2024 2025 /* restore original bundle: */ 2026 errno = 0; 2027 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]); 2028 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]); 2029 if (errno) { 2030 perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)"); 2031 return -1; 2032 } 2033 2034 /* restore original "ri" in ipsr: */ 2035 ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41); 2036 errno = 0; 2037 ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr); 2038 if (errno) { 2039 perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)"); 2040 return -1; 2041 } 2042 2043 tcp->flags &= ~TCB_BPTSET; 2044 2045 if (addr != (tcp->baddr & ~0x3)) { 2046 /* the breakpoint has not been reached yet. */ 2047 if (debug) 2048 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2049 addr, tcp->baddr); 2050 return 0; 2051 } 2052 } 2053# else /* !IA64 && !SPARC && !SPARC64 */ 2054 2055 if (debug) 2056 fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 2057 if (!(tcp->flags & TCB_BPTSET)) { 2058 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 2059 return -1; 2060 } 2061 errno = 0; 2062 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 2063 if (errno) { 2064 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 2065 return -1; 2066 } 2067 tcp->flags &= ~TCB_BPTSET; 2068 2069# ifdef I386 2070 if (upeek(tcp, 4*EIP, &eip) < 0) 2071 return -1; 2072 if (eip != tcp->baddr) { 2073 /* The breakpoint has not been reached yet. */ 2074 if (debug) 2075 fprintf(stderr, 2076 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2077 eip, tcp->baddr); 2078 return 0; 2079 } 2080# elif defined(X86_64) 2081 if (upeek(tcp, 8*RIP, &eip) < 0) 2082 return -1; 2083 if (eip != tcp->baddr) { 2084 /* The breakpoint has not been reached yet. */ 2085 if (debug) 2086 fprintf(stderr, 2087 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2088 eip, tcp->baddr); 2089 return 0; 2090 } 2091# elif defined(POWERPC) 2092 if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) 2093 return -1; 2094 if (pc != tcp->baddr) { 2095 /* The breakpoint has not been reached yet. */ 2096 if (debug) 2097 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2098 pc, tcp->baddr); 2099 return 0; 2100 } 2101# elif defined(M68K) 2102 if (upeek(tcp, 4*PT_PC, &pc) < 0) 2103 return -1; 2104 if (pc != tcp->baddr) { 2105 /* The breakpoint has not been reached yet. */ 2106 if (debug) 2107 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2108 pc, tcp->baddr); 2109 return 0; 2110 } 2111# elif defined(ALPHA) 2112 if (upeek(tcp, REG_PC, &pc) < 0) 2113 return -1; 2114 if (pc != tcp->baddr) { 2115 /* The breakpoint has not been reached yet. */ 2116 if (debug) 2117 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2118 pc, tcp->baddr); 2119 return 0; 2120 } 2121# elif defined(HPPA) 2122 if (upeek(tcp, PT_IAOQ0, &iaoq) < 0) 2123 return -1; 2124 iaoq &= ~0x03; 2125 if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) { 2126 /* The breakpoint has not been reached yet. */ 2127 if (debug) 2128 fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n", 2129 iaoq, tcp->baddr); 2130 return 0; 2131 } 2132 iaoq = tcp->baddr | 3; 2133 /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is 2134 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit 2135 * has no significant effect. 2136 */ 2137 ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq); 2138 ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq); 2139# elif defined(SH) 2140 if (upeek(tcp, 4*REG_PC, &pc) < 0) 2141 return -1; 2142 if (pc != tcp->baddr) { 2143 /* The breakpoint has not been reached yet. */ 2144 if (debug) 2145 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2146 pc, tcp->baddr); 2147 return 0; 2148 } 2149 2150# endif /* arch */ 2151# endif /* !SPARC && !SPARC64 && !IA64 */ 2152# endif /* LINUX */ 2153 2154# ifdef SUNOS4 2155# ifdef SPARC 2156 2157# if !LOOPA 2158 struct regs regs; 2159# endif 2160 2161 if (!(tcp->flags & TCB_BPTSET)) { 2162 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 2163 return -1; 2164 } 2165 if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 2166 sizeof tcp->inst, (char *) tcp->inst) < 0) { 2167 perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 2168 return -1; 2169 } 2170 tcp->flags &= ~TCB_BPTSET; 2171 2172# if !LOOPA 2173 /* 2174 * Since we don't have a single instruction breakpoint, we may have 2175 * to adjust the program counter after removing our `breakpoint'. 2176 */ 2177 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 2178 perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 2179 return -1; 2180 } 2181 if ((regs.r_pc < tcp->baddr) || 2182 (regs.r_pc > tcp->baddr + 4)) { 2183 /* The breakpoint has not been reached yet */ 2184 if (debug) 2185 fprintf(stderr, 2186 "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 2187 regs.r_pc, tcp->baddr); 2188 return 0; 2189 } 2190 if (regs.r_pc != tcp->baddr) 2191 if (debug) 2192 fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 2193 regs.r_pc, tcp->baddr); 2194 2195 regs.r_pc = tcp->baddr; 2196 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 2197 perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 2198 return -1; 2199 } 2200# endif /* LOOPA */ 2201# endif /* SPARC */ 2202# endif /* SUNOS4 */ 2203 2204 return 0; 2205} 2206 2207# endif /* !defined LINUX */ 2208 2209#endif /* !USE_PROCFS */ 2210 2211 2212#ifdef SUNOS4 2213 2214static int 2215getex(tcp, hdr) 2216struct tcb *tcp; 2217struct exec *hdr; 2218{ 2219 int n; 2220 2221 for (n = 0; n < sizeof *hdr; n += 4) { 2222 long res; 2223 if (upeek(tcp, uoff(u_exdata) + n, &res) < 0) 2224 return -1; 2225 memcpy(((char *) hdr) + n, &res, 4); 2226 } 2227 if (debug) { 2228 fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 2229 hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 2230 fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 2231 hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 2232 } 2233 return 0; 2234} 2235 2236int 2237fixvfork(tcp) 2238struct tcb *tcp; 2239{ 2240 int pid = tcp->pid; 2241 /* 2242 * Change `vfork' in a freshly exec'ed dynamically linked 2243 * executable's (internal) symbol table to plain old `fork' 2244 */ 2245 2246 struct exec hdr; 2247 struct link_dynamic dyn; 2248 struct link_dynamic_2 ld; 2249 char *strtab, *cp; 2250 2251 if (getex(tcp, &hdr) < 0) 2252 return -1; 2253 if (!hdr.a_dynamic) 2254 return -1; 2255 2256 if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 2257 fprintf(stderr, "Cannot read DYNAMIC\n"); 2258 return -1; 2259 } 2260 if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 2261 fprintf(stderr, "Cannot read link_dynamic_2\n"); 2262 return -1; 2263 } 2264 if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 2265 fprintf(stderr, "out of memory\n"); 2266 return -1; 2267 } 2268 if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 2269 (int)ld.ld_symb_size, strtab) < 0) 2270 goto err; 2271 2272# if 0 2273 for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 2274 fprintf(stderr, "[symbol: %s]\n", cp); 2275 cp += strlen(cp)+1; 2276 } 2277 return 0; 2278# endif 2279 for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 2280 if (strcmp(cp, "_vfork") == 0) { 2281 if (debug) 2282 fprintf(stderr, "fixvfork: FOUND _vfork\n"); 2283 strcpy(cp, "_fork"); 2284 break; 2285 } 2286 cp += strlen(cp)+1; 2287 } 2288 if (cp < strtab + ld.ld_symb_size) 2289 /* 2290 * Write entire symbol table back to avoid 2291 * memory alignment bugs in ptrace 2292 */ 2293 if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 2294 (int)ld.ld_symb_size, strtab) < 0) 2295 goto err; 2296 2297 free(strtab); 2298 return 0; 2299 2300err: 2301 free(strtab); 2302 return -1; 2303} 2304 2305#endif /* SUNOS4 */ 2306