util.c revision f535b54bc40373c81b13df0975aef4212dacbbde
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 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#ifndef USE_PROCFS 1380 1381#if defined LINUX 1382 1383#include "syscall.h" 1384 1385#include <sys/syscall.h> 1386#ifndef CLONE_PTRACE 1387# define CLONE_PTRACE 0x00002000 1388#endif 1389#ifndef CLONE_VFORK 1390# define CLONE_VFORK 0x00004000 1391#endif 1392#ifndef CLONE_VM 1393# define CLONE_VM 0x00000100 1394#endif 1395#ifndef CLONE_STOPPED 1396# define CLONE_STOPPED 0x02000000 1397#endif 1398 1399#ifdef IA64 1400 1401/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32 1402 subsystem has them for x86... */ 1403#define SYS_fork 2 1404#define SYS_vfork 190 1405 1406typedef unsigned long *arg_setup_state; 1407 1408static int 1409arg_setup(struct tcb *tcp, arg_setup_state *state) 1410{ 1411 unsigned long cfm, sof, sol; 1412 long bsp; 1413 1414 if (ia32) { 1415 /* Satisfy a false GCC warning. */ 1416 *state = NULL; 1417 return 0; 1418 } 1419 1420 if (upeek(tcp, PT_AR_BSP, &bsp) < 0) 1421 return -1; 1422 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0) 1423 return -1; 1424 1425 sof = (cfm >> 0) & 0x7f; 1426 sol = (cfm >> 7) & 0x7f; 1427 bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol); 1428 1429 *state = (unsigned long *) bsp; 1430 return 0; 1431} 1432 1433# define arg_finish_change(tcp, state) 0 1434 1435#ifdef SYS_fork 1436static int 1437get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp) 1438{ 1439 int ret; 1440 1441 if (ia32) 1442 ret = upeek (tcp, PT_R11, valp); 1443 else 1444 ret = umoven (tcp, 1445 (unsigned long) ia64_rse_skip_regs(*state, 0), 1446 sizeof(long), (void *) valp); 1447 return ret; 1448} 1449 1450static int 1451get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp) 1452{ 1453 int ret; 1454 1455 if (ia32) 1456 ret = upeek (tcp, PT_R9, valp); 1457 else 1458 ret = umoven (tcp, 1459 (unsigned long) ia64_rse_skip_regs(*state, 1), 1460 sizeof(long), (void *) valp); 1461 return ret; 1462} 1463#endif 1464 1465static int 1466set_arg0 (struct tcb *tcp, arg_setup_state *state, long val) 1467{ 1468 int req = PTRACE_POKEDATA; 1469 void *ap; 1470 1471 if (ia32) { 1472 ap = (void *) (intptr_t) PT_R11; /* r11 == EBX */ 1473 req = PTRACE_POKEUSER; 1474 } else 1475 ap = ia64_rse_skip_regs(*state, 0); 1476 errno = 0; 1477 ptrace(req, tcp->pid, ap, val); 1478 return errno ? -1 : 0; 1479} 1480 1481static int 1482set_arg1 (struct tcb *tcp, arg_setup_state *state, long val) 1483{ 1484 int req = PTRACE_POKEDATA; 1485 void *ap; 1486 1487 if (ia32) { 1488 ap = (void *) (intptr_t) PT_R9; /* r9 == ECX */ 1489 req = PTRACE_POKEUSER; 1490 } else 1491 ap = ia64_rse_skip_regs(*state, 1); 1492 errno = 0; 1493 ptrace(req, tcp->pid, ap, val); 1494 return errno ? -1 : 0; 1495} 1496 1497/* ia64 does not return the input arguments from functions (and syscalls) 1498 according to ia64 RSE (Register Stack Engine) behavior. */ 1499 1500# define restore_arg0(tcp, state, val) ((void) (state), 0) 1501# define restore_arg1(tcp, state, val) ((void) (state), 0) 1502 1503#elif defined (SPARC) || defined (SPARC64) 1504 1505typedef struct regs arg_setup_state; 1506 1507# define arg_setup(tcp, state) \ 1508 (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0)) 1509# define arg_finish_change(tcp, state) \ 1510 (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0)) 1511 1512# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0) 1513# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0) 1514# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0) 1515# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0) 1516# define restore_arg0(tcp, state, val) 0 1517 1518#else 1519 1520# if defined S390 || defined S390X 1521/* Note: this is only true for the `clone' system call, which handles 1522 arguments specially. We could as well say that its first two arguments 1523 are swapped relative to other architectures, but that would just be 1524 another #ifdef in the calls. */ 1525# define arg0_offset PT_GPR3 1526# define arg1_offset PT_ORIGGPR2 1527# define restore_arg0(tcp, state, val) ((void) (state), 0) 1528# define restore_arg1(tcp, state, val) ((void) (state), 0) 1529# define arg0_index 1 1530# define arg1_index 0 1531# elif defined (ALPHA) || defined (MIPS) 1532# define arg0_offset REG_A0 1533# define arg1_offset (REG_A0+1) 1534# elif defined (POWERPC) 1535# define arg0_offset (sizeof(unsigned long)*PT_R3) 1536# define arg1_offset (sizeof(unsigned long)*PT_R4) 1537# define restore_arg0(tcp, state, val) ((void) (state), 0) 1538# elif defined (HPPA) 1539# define arg0_offset PT_GR26 1540# define arg1_offset (PT_GR26-4) 1541# elif defined (X86_64) 1542# define arg0_offset ((long)(8*(current_personality ? RBX : RDI))) 1543# define arg1_offset ((long)(8*(current_personality ? RCX : RSI))) 1544# elif defined (SH) 1545# define arg0_offset (4*(REG_REG0+4)) 1546# define arg1_offset (4*(REG_REG0+5)) 1547# elif defined (SH64) 1548 /* ABI defines arg0 & 1 in r2 & r3 */ 1549# define arg0_offset (REG_OFFSET+16) 1550# define arg1_offset (REG_OFFSET+24) 1551# define restore_arg0(tcp, state, val) 0 1552# else 1553# define arg0_offset 0 1554# define arg1_offset 4 1555# if defined ARM 1556# define restore_arg0(tcp, state, val) 0 1557# endif 1558# endif 1559 1560typedef int arg_setup_state; 1561 1562# define arg_setup(tcp, state) (0) 1563# define arg_finish_change(tcp, state) 0 1564# define get_arg0(tcp, cookie, valp) \ 1565 (upeek ((tcp), arg0_offset, (valp))) 1566# define get_arg1(tcp, cookie, valp) \ 1567 (upeek ((tcp), arg1_offset, (valp))) 1568 1569static int 1570set_arg0 (struct tcb *tcp, void *cookie, long val) 1571{ 1572 return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val); 1573} 1574 1575static int 1576set_arg1 (struct tcb *tcp, void *cookie, long val) 1577{ 1578 return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val); 1579} 1580 1581#endif 1582 1583#ifndef restore_arg0 1584# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val)) 1585#endif 1586#ifndef restore_arg1 1587# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val)) 1588#endif 1589 1590#ifndef arg0_index 1591# define arg0_index 0 1592# define arg1_index 1 1593#endif 1594 1595int 1596setbpt(tcp) 1597struct tcb *tcp; 1598{ 1599 static int clone_scno[SUPPORTED_PERSONALITIES] = { SYS_clone }; 1600 extern int change_syscall(struct tcb *, int); 1601 arg_setup_state state; 1602 1603 if (tcp->flags & TCB_BPTSET) { 1604 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1605 return -1; 1606 } 1607 1608 /* 1609 * It's a silly kludge to initialize this with a search at runtime. 1610 * But it's better than maintaining another magic thing in the 1611 * godforsaken tables. 1612 */ 1613 if (clone_scno[current_personality] == 0) { 1614 int i; 1615 for (i = 0; i < nsyscalls; ++i) 1616 if (sysent[i].sys_func == sys_clone) { 1617 clone_scno[current_personality] = i; 1618 break; 1619 } 1620 } 1621 1622 switch (known_scno(tcp)) { 1623#ifdef SYS_vfork 1624 case SYS_vfork: 1625#endif 1626#ifdef SYS_fork 1627 case SYS_fork: 1628#endif 1629#if defined SYS_fork || defined SYS_vfork 1630 if (arg_setup (tcp, &state) < 0 1631 || get_arg0 (tcp, &state, &tcp->inst[0]) < 0 1632 || get_arg1 (tcp, &state, &tcp->inst[1]) < 0 1633 || change_syscall(tcp, clone_scno[current_personality]) < 0 1634 || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 1635 || set_arg1 (tcp, &state, 0) < 0 1636 || arg_finish_change (tcp, &state) < 0) 1637 return -1; 1638 tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD; 1639 tcp->u_arg[arg1_index] = 0; 1640 tcp->flags |= TCB_BPTSET; 1641 return 0; 1642#endif 1643 1644 case SYS_clone: 1645#ifdef SYS_clone2 1646 case SYS_clone2: 1647#endif 1648 /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)' 1649 contrary to x86 SYS_vfork above. Even on x86 we turn the 1650 vfork semantics into plain fork - each application must not 1651 depend on the vfork specifics according to POSIX. We would 1652 hang waiting for the parent resume otherwise. We need to 1653 clear also CLONE_VM but only in the CLONE_VFORK case as 1654 otherwise we would break pthread_create. */ 1655 1656 if ((arg_setup (tcp, &state) < 0 1657 || set_arg0 (tcp, &state, 1658 (tcp->u_arg[arg0_index] | CLONE_PTRACE) 1659 & ~(tcp->u_arg[arg0_index] & CLONE_VFORK 1660 ? CLONE_VFORK | CLONE_VM : 0)) < 0 1661 || arg_finish_change (tcp, &state) < 0)) 1662 return -1; 1663 tcp->flags |= TCB_BPTSET; 1664 tcp->inst[0] = tcp->u_arg[arg0_index]; 1665 tcp->inst[1] = tcp->u_arg[arg1_index]; 1666 return 0; 1667 1668 default: 1669 fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n", 1670 tcp->scno, tcp->pid); 1671 break; 1672 } 1673 1674 return -1; 1675} 1676 1677int 1678clearbpt(tcp) 1679struct tcb *tcp; 1680{ 1681 arg_setup_state state; 1682 if (arg_setup (tcp, &state) < 0 1683 || restore_arg0 (tcp, &state, tcp->inst[0]) < 0 1684 || restore_arg1 (tcp, &state, tcp->inst[1]) < 0 1685 || arg_finish_change (tcp, &state)) 1686 return -1; 1687 tcp->flags &= ~TCB_BPTSET; 1688 return 0; 1689} 1690 1691#else 1692 1693int 1694setbpt(tcp) 1695struct tcb *tcp; 1696{ 1697 1698#ifdef LINUX 1699#if defined (SPARC) || defined (SPARC64) 1700 /* We simply use the SunOS breakpoint code. */ 1701 1702 struct regs regs; 1703 unsigned long inst; 1704#define LOOPA 0x30800000 /* ba,a 0 */ 1705 1706 if (tcp->flags & TCB_BPTSET) { 1707 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1708 return -1; 1709 } 1710 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1711 perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 1712 return -1; 1713 } 1714 tcp->baddr = regs.r_o7 + 8; 1715 errno = 0; 1716 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0); 1717 if(errno) { 1718 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1719 return -1; 1720 } 1721 1722 /* 1723 * XXX - BRUTAL MODE ON 1724 * We cannot set a real BPT in the child, since it will not be 1725 * traced at the moment it will reach the trap and would probably 1726 * die with a core dump. 1727 * Thus, we are force our way in by taking out two instructions 1728 * and insert an eternal loop instead, in expectance of the SIGSTOP 1729 * generated by out PTRACE_ATTACH. 1730 * Of cause, if we evaporate ourselves in the middle of all this... 1731 */ 1732 errno = 0; 1733 inst = LOOPA; 1734#if defined (SPARC64) 1735 inst <<= 32; 1736 inst |= (tcp->inst[0] & 0xffffffffUL); 1737#endif 1738 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst); 1739 if(errno) { 1740 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1741 return -1; 1742 } 1743 tcp->flags |= TCB_BPTSET; 1744 1745#else /* !SPARC && !SPARC64 */ 1746#ifdef IA64 1747 if (ia32) { 1748# define LOOP 0x0000feeb 1749 if (tcp->flags & TCB_BPTSET) { 1750 fprintf(stderr, "PANIC: bpt already set in pid %u\n", 1751 tcp->pid); 1752 return -1; 1753 } 1754 if (upeek(tcp, PT_CR_IIP, &tcp->baddr) < 0) 1755 return -1; 1756 if (debug) 1757 fprintf(stderr, "[%d] setting bpt at %lx\n", 1758 tcp->pid, tcp->baddr); 1759 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, 1760 (char *) tcp->baddr, 0); 1761 if (errno) { 1762 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1763 return -1; 1764 } 1765 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 1766 if (errno) { 1767 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1768 return -1; 1769 } 1770 tcp->flags |= TCB_BPTSET; 1771 } else { 1772 /* 1773 * Our strategy here is to replace the bundle that 1774 * contained the clone() syscall with a bundle of the 1775 * form: 1776 * 1777 * { 1: br 1b; br 1b; br 1b } 1778 * 1779 * This ensures that the newly forked child will loop 1780 * endlessly until we've got a chance to attach to it. 1781 */ 1782# define LOOP0 0x0000100000000017 1783# define LOOP1 0x4000000000200000 1784 unsigned long addr, ipsr; 1785 pid_t pid; 1786 1787 pid = tcp->pid; 1788 if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0) 1789 return -1; 1790 if (upeek(tcp, PT_CR_IIP, &addr) < 0) 1791 return -1; 1792 /* store "ri" in low two bits */ 1793 tcp->baddr = addr | ((ipsr >> 41) & 0x3); 1794 1795 errno = 0; 1796 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0, 1797 0); 1798 tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8, 1799 0); 1800 if (errno) { 1801 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1802 return -1; 1803 } 1804 1805 errno = 0; 1806 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0); 1807 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1); 1808 if (errno) { 1809 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1810 return -1; 1811 } 1812 tcp->flags |= TCB_BPTSET; 1813 } 1814#else /* !IA64 */ 1815 1816#if defined (I386) || defined(X86_64) 1817#define LOOP 0x0000feeb 1818#elif defined (M68K) 1819#define LOOP 0x60fe0000 1820#elif defined (ALPHA) 1821#define LOOP 0xc3ffffff 1822#elif defined (POWERPC) 1823#define LOOP 0x48000000 1824#elif defined(ARM) 1825#define LOOP 0xEAFFFFFE 1826#elif defined(MIPS) 1827#define LOOP 0x1000ffff 1828#elif defined(S390) 1829#define LOOP 0xa7f40000 /* BRC 15,0 */ 1830#elif defined(S390X) 1831#define LOOP 0xa7f4000000000000UL /* BRC 15,0 */ 1832#elif defined(HPPA) 1833#define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */ 1834#elif defined(SH) 1835#ifdef __LITTLE_ENDIAN__ 1836#define LOOP 0x0000affe 1837#else 1838#define LOOP 0xfeaf0000 1839#endif 1840#else 1841#error unknown architecture 1842#endif 1843 1844 if (tcp->flags & TCB_BPTSET) { 1845 fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid); 1846 return -1; 1847 } 1848#if defined (I386) 1849 if (upeek(tcp, 4*EIP, &tcp->baddr) < 0) 1850 return -1; 1851#elif defined (X86_64) 1852 if (upeek(tcp, 8*RIP, &tcp->baddr) < 0) 1853 return -1; 1854#elif defined (M68K) 1855 if (upeek(tcp, 4*PT_PC, &tcp->baddr) < 0) 1856 return -1; 1857#elif defined (ALPHA) 1858 return -1; 1859#elif defined (ARM) 1860 return -1; 1861#elif defined (MIPS) 1862 return -1; /* FIXME: I do not know what i do - Flo */ 1863#elif defined (POWERPC) 1864 if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0) 1865 return -1; 1866#elif defined(S390) || defined(S390X) 1867 if (upeek(tcp,PT_PSWADDR, &tcp->baddr) < 0) 1868 return -1; 1869#elif defined(HPPA) 1870 if (upeek(tcp, PT_IAOQ0, &tcp->baddr) < 0) 1871 return -1; 1872 tcp->baddr &= ~0x03; 1873#elif defined(SH) 1874 if (upeek(tcp, 4*REG_PC, &tcp->baddr) < 0) 1875 return -1; 1876#else 1877#error unknown architecture 1878#endif 1879 if (debug) 1880 fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr); 1881 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0); 1882 if (errno) { 1883 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); 1884 return -1; 1885 } 1886 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); 1887 if (errno) { 1888 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); 1889 return -1; 1890 } 1891 tcp->flags |= TCB_BPTSET; 1892 1893#endif /* !IA64 */ 1894#endif /* SPARC || SPARC64 */ 1895#endif /* LINUX */ 1896 1897#ifdef SUNOS4 1898#ifdef SPARC /* This code is slightly sparc specific */ 1899 1900 struct regs regs; 1901#define BPT 0x91d02001 /* ta 1 */ 1902#define LOOP 0x10800000 /* ba 0 */ 1903#define LOOPA 0x30800000 /* ba,a 0 */ 1904#define NOP 0x01000000 1905#if LOOPA 1906 static int loopdeloop[1] = {LOOPA}; 1907#else 1908 static int loopdeloop[2] = {LOOP, NOP}; 1909#endif 1910 1911 if (tcp->flags & TCB_BPTSET) { 1912 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid); 1913 return -1; 1914 } 1915 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 1916 perror("setbpt: ptrace(PTRACE_GETREGS, ...)"); 1917 return -1; 1918 } 1919 tcp->baddr = regs.r_o7 + 8; 1920 if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr, 1921 sizeof tcp->inst, (char *)tcp->inst) < 0) { 1922 perror("setbpt: ptrace(PTRACE_READTEXT, ...)"); 1923 return -1; 1924 } 1925 1926 /* 1927 * XXX - BRUTAL MODE ON 1928 * We cannot set a real BPT in the child, since it will not be 1929 * traced at the moment it will reach the trap and would probably 1930 * die with a core dump. 1931 * Thus, we are force our way in by taking out two instructions 1932 * and insert an eternal loop in stead, in expectance of the SIGSTOP 1933 * generated by out PTRACE_ATTACH. 1934 * Of cause, if we evaporate ourselves in the middle of all this... 1935 */ 1936 if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 1937 sizeof loopdeloop, (char *) loopdeloop) < 0) { 1938 perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)"); 1939 return -1; 1940 } 1941 tcp->flags |= TCB_BPTSET; 1942 1943#endif /* SPARC */ 1944#endif /* SUNOS4 */ 1945 1946 return 0; 1947} 1948 1949int 1950clearbpt(tcp) 1951struct tcb *tcp; 1952{ 1953 1954#ifdef LINUX 1955#if defined(I386) || defined(X86_64) 1956 long eip; 1957#elif defined(POWERPC) 1958 long pc; 1959#elif defined(M68K) 1960 long pc; 1961#elif defined(ALPHA) 1962 long pc; 1963#elif defined(HPPA) 1964 long iaoq; 1965#elif defined(SH) 1966 long pc; 1967#endif /* architecture */ 1968 1969#if defined (SPARC) || defined (SPARC64) 1970 /* Again, we borrow the SunOS breakpoint code. */ 1971 if (!(tcp->flags & TCB_BPTSET)) { 1972 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 1973 return -1; 1974 } 1975 errno = 0; 1976 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 1977 if(errno) { 1978 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 1979 return -1; 1980 } 1981 tcp->flags &= ~TCB_BPTSET; 1982#elif defined(IA64) 1983 if (ia32) { 1984 unsigned long addr; 1985 1986 if (debug) 1987 fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 1988 if (!(tcp->flags & TCB_BPTSET)) { 1989 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 1990 return -1; 1991 } 1992 errno = 0; 1993 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 1994 if (errno) { 1995 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 1996 return -1; 1997 } 1998 tcp->flags &= ~TCB_BPTSET; 1999 2000 if (upeek(tcp, PT_CR_IIP, &addr) < 0) 2001 return -1; 2002 if (addr != tcp->baddr) { 2003 /* The breakpoint has not been reached yet. */ 2004 if (debug) 2005 fprintf(stderr, 2006 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2007 addr, tcp->baddr); 2008 return 0; 2009 } 2010 } else { 2011 unsigned long addr, ipsr; 2012 pid_t pid; 2013 2014 pid = tcp->pid; 2015 2016 if (upeek(tcp, PT_CR_IPSR, &ipsr) < 0) 2017 return -1; 2018 if (upeek(tcp, PT_CR_IIP, &addr) < 0) 2019 return -1; 2020 2021 /* restore original bundle: */ 2022 errno = 0; 2023 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]); 2024 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]); 2025 if (errno) { 2026 perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)"); 2027 return -1; 2028 } 2029 2030 /* restore original "ri" in ipsr: */ 2031 ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41); 2032 errno = 0; 2033 ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr); 2034 if (errno) { 2035 perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)"); 2036 return -1; 2037 } 2038 2039 tcp->flags &= ~TCB_BPTSET; 2040 2041 if (addr != (tcp->baddr & ~0x3)) { 2042 /* the breakpoint has not been reached yet. */ 2043 if (debug) 2044 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2045 addr, tcp->baddr); 2046 return 0; 2047 } 2048 } 2049#else /* !IA64 && !SPARC && !SPARC64 */ 2050 2051 if (debug) 2052 fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); 2053 if (!(tcp->flags & TCB_BPTSET)) { 2054 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 2055 return -1; 2056 } 2057 errno = 0; 2058 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); 2059 if (errno) { 2060 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); 2061 return -1; 2062 } 2063 tcp->flags &= ~TCB_BPTSET; 2064 2065#ifdef I386 2066 if (upeek(tcp, 4*EIP, &eip) < 0) 2067 return -1; 2068 if (eip != tcp->baddr) { 2069 /* The breakpoint has not been reached yet. */ 2070 if (debug) 2071 fprintf(stderr, 2072 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2073 eip, tcp->baddr); 2074 return 0; 2075 } 2076#elif defined(X86_64) 2077 if (upeek(tcp, 8*RIP, &eip) < 0) 2078 return -1; 2079 if (eip != tcp->baddr) { 2080 /* The breakpoint has not been reached yet. */ 2081 if (debug) 2082 fprintf(stderr, 2083 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2084 eip, tcp->baddr); 2085 return 0; 2086 } 2087#elif defined(POWERPC) 2088 if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) 2089 return -1; 2090 if (pc != tcp->baddr) { 2091 /* The breakpoint has not been reached yet. */ 2092 if (debug) 2093 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2094 pc, tcp->baddr); 2095 return 0; 2096 } 2097#elif defined(M68K) 2098 if (upeek(tcp, 4*PT_PC, &pc) < 0) 2099 return -1; 2100 if (pc != tcp->baddr) { 2101 /* The breakpoint has not been reached yet. */ 2102 if (debug) 2103 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2104 pc, tcp->baddr); 2105 return 0; 2106 } 2107#elif defined(ALPHA) 2108 if (upeek(tcp, REG_PC, &pc) < 0) 2109 return -1; 2110 if (pc != tcp->baddr) { 2111 /* The breakpoint has not been reached yet. */ 2112 if (debug) 2113 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2114 pc, tcp->baddr); 2115 return 0; 2116 } 2117#elif defined(HPPA) 2118 if (upeek(tcp, PT_IAOQ0, &iaoq) < 0) 2119 return -1; 2120 iaoq &= ~0x03; 2121 if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) { 2122 /* The breakpoint has not been reached yet. */ 2123 if (debug) 2124 fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n", 2125 iaoq, tcp->baddr); 2126 return 0; 2127 } 2128 iaoq = tcp->baddr | 3; 2129 /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is 2130 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit 2131 * has no significant effect. 2132 */ 2133 ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq); 2134 ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq); 2135#elif defined(SH) 2136 if (upeek(tcp, 4*REG_PC, &pc) < 0) 2137 return -1; 2138 if (pc != tcp->baddr) { 2139 /* The breakpoint has not been reached yet. */ 2140 if (debug) 2141 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", 2142 pc, tcp->baddr); 2143 return 0; 2144 } 2145 2146#endif /* arch */ 2147#endif /* !SPARC && !SPARC64 && !IA64 */ 2148#endif /* LINUX */ 2149 2150#ifdef SUNOS4 2151#ifdef SPARC 2152 2153#if !LOOPA 2154 struct regs regs; 2155#endif 2156 2157 if (!(tcp->flags & TCB_BPTSET)) { 2158 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); 2159 return -1; 2160 } 2161 if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr, 2162 sizeof tcp->inst, (char *) tcp->inst) < 0) { 2163 perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)"); 2164 return -1; 2165 } 2166 tcp->flags &= ~TCB_BPTSET; 2167 2168#if !LOOPA 2169 /* 2170 * Since we don't have a single instruction breakpoint, we may have 2171 * to adjust the program counter after removing the our `breakpoint'. 2172 */ 2173 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { 2174 perror("clearbpt: ptrace(PTRACE_GETREGS, ...)"); 2175 return -1; 2176 } 2177 if ((regs.r_pc < tcp->baddr) || 2178 (regs.r_pc > tcp->baddr + 4)) { 2179 /* The breakpoint has not been reached yet */ 2180 if (debug) 2181 fprintf(stderr, 2182 "NOTE: PC not at bpt (pc %#x baddr %#x)\n", 2183 regs.r_pc, tcp->parent->baddr); 2184 return 0; 2185 } 2186 if (regs.r_pc != tcp->baddr) 2187 if (debug) 2188 fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n", 2189 regs.r_pc, tcp->baddr); 2190 2191 regs.r_pc = tcp->baddr; 2192 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) { 2193 perror("clearbpt: ptrace(PTRACE_SETREGS, ...)"); 2194 return -1; 2195 } 2196#endif /* LOOPA */ 2197#endif /* SPARC */ 2198#endif /* SUNOS4 */ 2199 2200 return 0; 2201} 2202 2203#endif 2204 2205#endif /* !USE_PROCFS */ 2206 2207#ifdef SUNOS4 2208 2209static int 2210getex(tcp, hdr) 2211struct tcb *tcp; 2212struct exec *hdr; 2213{ 2214 int n; 2215 2216 for (n = 0; n < sizeof *hdr; n += 4) { 2217 long res; 2218 if (upeek(tcp, uoff(u_exdata) + n, &res) < 0) 2219 return -1; 2220 memcpy(((char *) hdr) + n, &res, 4); 2221 } 2222 if (debug) { 2223 fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n", 2224 hdr->a_magic, hdr->a_toolversion, hdr->a_machtype); 2225 fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n", 2226 hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry); 2227 } 2228 return 0; 2229} 2230 2231int 2232fixvfork(tcp) 2233struct tcb *tcp; 2234{ 2235 int pid = tcp->pid; 2236 /* 2237 * Change `vfork' in a freshly exec'ed dynamically linked 2238 * executable's (internal) symbol table to plain old `fork' 2239 */ 2240 2241 struct exec hdr; 2242 struct link_dynamic dyn; 2243 struct link_dynamic_2 ld; 2244 char *strtab, *cp; 2245 2246 if (getex(tcp, &hdr) < 0) 2247 return -1; 2248 if (!hdr.a_dynamic) 2249 return -1; 2250 2251 if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) { 2252 fprintf(stderr, "Cannot read DYNAMIC\n"); 2253 return -1; 2254 } 2255 if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) { 2256 fprintf(stderr, "Cannot read link_dynamic_2\n"); 2257 return -1; 2258 } 2259 if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) { 2260 fprintf(stderr, "out of memory\n"); 2261 return -1; 2262 } 2263 if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 2264 (int)ld.ld_symb_size, strtab) < 0) 2265 goto err; 2266 2267#if 0 2268 for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 2269 fprintf(stderr, "[symbol: %s]\n", cp); 2270 cp += strlen(cp)+1; 2271 } 2272 return 0; 2273#endif 2274 for (cp = strtab; cp < strtab + ld.ld_symb_size; ) { 2275 if (strcmp(cp, "_vfork") == 0) { 2276 if (debug) 2277 fprintf(stderr, "fixvfork: FOUND _vfork\n"); 2278 strcpy(cp, "_fork"); 2279 break; 2280 } 2281 cp += strlen(cp)+1; 2282 } 2283 if (cp < strtab + ld.ld_symb_size) 2284 /* 2285 * Write entire symbol table back to avoid 2286 * memory alignment bugs in ptrace 2287 */ 2288 if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr), 2289 (int)ld.ld_symb_size, strtab) < 0) 2290 goto err; 2291 2292 free(strtab); 2293 return 0; 2294 2295err: 2296 free(strtab); 2297 return -1; 2298} 2299 2300#endif /* SUNOS4 */ 2301