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