process.c revision b69f81b8e552ab9ecdc5605887458adb0cb9542a
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 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH 10 * port by Greg Banks <gbanks@pocketpenguins.com> 11 12 * 13 * All rights reserved. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 3. The name of the author may not be used to endorse or promote products 24 * derived from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * $Id$ 38 */ 39 40#include "defs.h" 41 42#include <fcntl.h> 43#include <sys/stat.h> 44#include <sys/time.h> 45#include <sys/wait.h> 46#include <sys/resource.h> 47#include <sys/utsname.h> 48#include <sys/user.h> 49#include <sys/syscall.h> 50#include <signal.h> 51#ifdef SUNOS4 52#include <machine/reg.h> 53#endif /* SUNOS4 */ 54 55#ifdef FREEBSD 56#include <sys/ptrace.h> 57#endif 58 59#if HAVE_ASM_REG_H 60#ifdef SPARC 61# define fpq kernel_fpq 62# define fq kernel_fq 63# define fpu kernel_fpu 64#endif 65#include <asm/reg.h> 66#ifdef SPARC 67# undef fpq 68# undef fq 69# undef fpu 70#endif 71#endif /* HAVE_ASM_REG_H */ 72 73#ifdef HAVE_SYS_REG_H 74# include <sys/reg.h> 75#ifndef PTRACE_PEEKUSR 76# define PTRACE_PEEKUSR PTRACE_PEEKUSER 77#endif 78#ifndef PTRACE_POKEUSR 79# define PTRACE_POKEUSR PTRACE_POKEUSER 80#endif 81#elif defined(HAVE_LINUX_PTRACE_H) 82#undef PTRACE_SYSCALL 83#include <linux/ptrace.h> 84#endif 85 86#ifdef HAVE_LINUX_FUTEX_H 87#include <linux/futex.h> 88#endif 89#if defined LINUX 90# ifndef FUTEX_WAIT 91# define FUTEX_WAIT 0 92# endif 93# ifndef FUTEX_WAKE 94# define FUTEX_WAKE 1 95# endif 96# ifndef FUTEX_FD 97# define FUTEX_FD 2 98# endif 99#endif 100 101#ifdef LINUX 102#include <asm/posix_types.h> 103#undef GETGROUPS_T 104#define GETGROUPS_T __kernel_gid_t 105#endif /* LINUX */ 106 107#if defined(LINUX) && defined(IA64) 108# include <asm/ptrace_offsets.h> 109# include <asm/rse.h> 110#endif 111 112#ifdef HAVE_PRCTL 113#include <sys/prctl.h> 114#endif 115 116#ifndef WCOREDUMP 117#define WCOREDUMP(status) ((status) & 0200) 118#endif 119 120/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */ 121#if defined(HAVE_PRCTL) 122static struct xlat prctl_options[] = { 123#ifdef PR_MAXPROCS 124 { PR_MAXPROCS, "PR_MAXPROCS" }, 125#endif 126#ifdef PR_ISBLOCKED 127 { PR_ISBLOCKED, "PR_ISBLOCKED" }, 128#endif 129#ifdef PR_SETSTACKSIZE 130 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" }, 131#endif 132#ifdef PR_GETSTACKSIZE 133 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" }, 134#endif 135#ifdef PR_MAXPPROCS 136 { PR_MAXPPROCS, "PR_MAXPPROCS" }, 137#endif 138#ifdef PR_UNBLKONEXEC 139 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" }, 140#endif 141#ifdef PR_ATOMICSIM 142 { PR_ATOMICSIM, "PR_ATOMICSIM" }, 143#endif 144#ifdef PR_SETEXITSIG 145 { PR_SETEXITSIG, "PR_SETEXITSIG" }, 146#endif 147#ifdef PR_RESIDENT 148 { PR_RESIDENT, "PR_RESIDENT" }, 149#endif 150#ifdef PR_ATTACHADDR 151 { PR_ATTACHADDR, "PR_ATTACHADDR" }, 152#endif 153#ifdef PR_DETACHADDR 154 { PR_DETACHADDR, "PR_DETACHADDR" }, 155#endif 156#ifdef PR_TERMCHILD 157 { PR_TERMCHILD, "PR_TERMCHILD" }, 158#endif 159#ifdef PR_GETSHMASK 160 { PR_GETSHMASK, "PR_GETSHMASK" }, 161#endif 162#ifdef PR_GETNSHARE 163 { PR_GETNSHARE, "PR_GETNSHARE" }, 164#endif 165#if defined(PR_SET_PDEATHSIG) 166 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" }, 167#endif 168#ifdef PR_COREPID 169 { PR_COREPID, "PR_COREPID" }, 170#endif 171#ifdef PR_ATTACHADDRPERM 172 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" }, 173#endif 174#ifdef PR_PTHREADEXIT 175 { PR_PTHREADEXIT, "PR_PTHREADEXIT" }, 176#endif 177#ifdef PR_SET_PDEATHSIG 178 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" }, 179#endif 180#ifdef PR_GET_PDEATHSIG 181 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" }, 182#endif 183#ifdef PR_GET_UNALIGN 184 { PR_GET_UNALIGN, "PR_GET_UNALIGN" }, 185#endif 186#ifdef PR_SET_UNALIGN 187 { PR_SET_UNALIGN, "PR_SET_UNALIGN" }, 188#endif 189#ifdef PR_GET_KEEPCAPS 190 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" }, 191#endif 192#ifdef PR_SET_KEEPCAPS 193 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" }, 194#endif 195 { 0, NULL }, 196}; 197 198 199const char * 200unalignctl_string (unsigned int ctl) 201{ 202 static char buf[16]; 203 204 switch (ctl) { 205#ifdef PR_UNALIGN_NOPRINT 206 case PR_UNALIGN_NOPRINT: 207 return "NOPRINT"; 208#endif 209#ifdef PR_UNALIGN_SIGBUS 210 case PR_UNALIGN_SIGBUS: 211 return "SIGBUS"; 212#endif 213 default: 214 break; 215 } 216 sprintf(buf, "%x", ctl); 217 return buf; 218} 219 220 221int 222sys_prctl(tcp) 223struct tcb *tcp; 224{ 225 int i; 226 227 if (entering(tcp)) { 228 printxval(prctl_options, tcp->u_arg[0], "PR_???"); 229 switch (tcp->u_arg[0]) { 230#ifdef PR_GETNSHARE 231 case PR_GETNSHARE: 232 break; 233#endif 234#ifdef PR_SET_DEATHSIG 235 case PR_GET_PDEATHSIG: 236 break; 237#endif 238#ifdef PR_SET_UNALIGN 239 case PR_SET_UNALIGN: 240 tprintf(", %s", unalignctl_string(tcp->u_arg[1])); 241 break; 242#endif 243#ifdef PR_GET_UNALIGN 244 case PR_GET_UNALIGN: 245 tprintf(", %#lx", tcp->u_arg[1]); 246 break; 247#endif 248 default: 249 for (i = 1; i < tcp->u_nargs; i++) 250 tprintf(", %#lx", tcp->u_arg[i]); 251 break; 252 } 253 } else { 254 switch (tcp->u_arg[0]) { 255#ifdef PR_GET_PDEATHSIG 256 case PR_GET_PDEATHSIG: 257 for (i=1; i<tcp->u_nargs; i++) 258 tprintf(", %#lx", tcp->u_arg[i]); 259 break; 260#endif 261#ifdef PR_SET_UNALIGN 262 case PR_SET_UNALIGN: 263 break; 264#endif 265#ifdef PR_GET_UNALIGN 266 case PR_GET_UNALIGN: 267 { 268 int ctl; 269 270 umove(tcp, tcp->u_arg[1], &ctl); 271 tcp->auxstr = unalignctl_string(ctl); 272 return RVAL_STR; 273 } 274#endif 275 default: 276 break; 277 } 278 } 279 return 0; 280} 281 282#endif /* HAVE_PRCTL */ 283 284int 285sys_gethostid(tcp) 286struct tcb *tcp; 287{ 288 if (exiting(tcp)) 289 return RVAL_HEX; 290 return 0; 291} 292 293int 294sys_sethostname(tcp) 295struct tcb *tcp; 296{ 297 if (entering(tcp)) { 298 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]); 299 tprintf(", %lu", tcp->u_arg[1]); 300 } 301 return 0; 302} 303 304int 305sys_gethostname(tcp) 306struct tcb *tcp; 307{ 308 if (exiting(tcp)) { 309 if (syserror(tcp)) 310 tprintf("%#lx", tcp->u_arg[0]); 311 else 312 printpath(tcp, tcp->u_arg[0]); 313 tprintf(", %lu", tcp->u_arg[1]); 314 } 315 return 0; 316} 317 318int 319sys_setdomainname(tcp) 320struct tcb *tcp; 321{ 322 if (entering(tcp)) { 323 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]); 324 tprintf(", %lu", tcp->u_arg[1]); 325 } 326 return 0; 327} 328 329#if !defined(LINUX) 330 331int 332sys_getdomainname(tcp) 333struct tcb *tcp; 334{ 335 if (exiting(tcp)) { 336 if (syserror(tcp)) 337 tprintf("%#lx", tcp->u_arg[0]); 338 else 339 printpath(tcp, tcp->u_arg[0]); 340 tprintf(", %lu", tcp->u_arg[1]); 341 } 342 return 0; 343} 344#endif /* !LINUX */ 345 346int 347sys_exit(tcp) 348struct tcb *tcp; 349{ 350 if (exiting(tcp)) { 351 fprintf(stderr, "_exit returned!\n"); 352 return -1; 353 } 354 /* special case: we stop tracing this process, finish line now */ 355 tprintf("%ld) ", tcp->u_arg[0]); 356 tabto(acolumn); 357 tprintf("= ?"); 358 printtrailer(tcp); 359 return 0; 360} 361 362int 363internal_exit(tcp) 364struct tcb *tcp; 365{ 366 if (entering(tcp)) 367 tcp->flags |= TCB_EXITING; 368 return 0; 369} 370 371/* TCP is creating a child we want to follow. 372 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0. 373 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */ 374static int 375fork_tcb(struct tcb *tcp) 376{ 377 if (nprocs == tcbtabsize) { 378 /* Allocate some more TCBs and expand the table. 379 We don't want to relocate the TCBs because our 380 callers have pointers and it would be a pain. 381 So tcbtab is a table of pointers. Since we never 382 free the TCBs, we allocate a single chunk of many. */ 383 struct tcb **newtab = (struct tcb **) 384 realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]); 385 struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize, 386 sizeof *newtcbs); 387 int i; 388 if (newtab == NULL || newtcbs == NULL) { 389 if (newtab != NULL) 390 free(newtab); 391 tcp->flags &= ~TCB_FOLLOWFORK; 392 fprintf(stderr, "sys_fork: tcb table full\n"); 393 return 1; 394 } 395 for (i = tcbtabsize; i < 2 * tcbtabsize; ++i) 396 newtab[i] = &newtcbs[i - tcbtabsize]; 397 tcbtabsize *= 2; 398 tcbtab = newtab; 399 } 400 401 tcp->flags |= TCB_FOLLOWFORK; 402 return 0; 403} 404 405#ifdef USE_PROCFS 406 407int 408sys_fork(tcp) 409struct tcb *tcp; 410{ 411 if (exiting(tcp)) { 412 if (getrval2(tcp)) { 413 tcp->auxstr = "child process"; 414 return RVAL_UDECIMAL | RVAL_STR; 415 } 416 } 417 return 0; 418} 419 420#if UNIXWARE > 2 421 422int 423sys_rfork(tcp) 424struct tcb *tcp; 425{ 426 if (entering(tcp)) { 427 tprintf ("%ld", tcp->u_arg[0]); 428 } 429 else { 430 if (getrval2(tcp)) { 431 tcp->auxstr = "child process"; 432 return RVAL_UDECIMAL | RVAL_STR; 433 } 434 } 435 return 0; 436} 437 438#endif 439 440int 441internal_fork(tcp) 442struct tcb *tcp; 443{ 444 struct tcb *tcpchild; 445 446 if (exiting(tcp)) { 447 if (getrval2(tcp)) 448 return 0; 449 if (!followfork) 450 return 0; 451 if (fork_tcb(tcp)) 452 return 0; 453 if (syserror(tcp)) 454 return 0; 455 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) { 456 fprintf(stderr, "sys_fork: tcb table full\n"); 457 return 0; 458 } 459 if (proc_open(tcpchild, 2) < 0) 460 droptcb(tcpchild); 461 } 462 return 0; 463} 464 465#else /* !USE_PROCFS */ 466 467#ifdef LINUX 468 469/* defines copied from linux/sched.h since we can't include that 470 * ourselves (it conflicts with *lots* of libc includes) 471 */ 472#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ 473#define CLONE_VM 0x00000100 /* set if VM shared between processes */ 474#define CLONE_FS 0x00000200 /* set if fs info shared between processes */ 475#define CLONE_FILES 0x00000400 /* set if open files shared between processes */ 476#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */ 477#define CLONE_PID 0x00001000 /* set if pid shared */ 478#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */ 479#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */ 480#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */ 481 482static struct xlat clone_flags[] = { 483 { CLONE_VM, "CLONE_VM" }, 484 { CLONE_FS, "CLONE_FS" }, 485 { CLONE_FILES, "CLONE_FILES" }, 486 { CLONE_SIGHAND, "CLONE_SIGHAND" }, 487 { CLONE_PID, "CLONE_PID" }, 488 { CLONE_PTRACE, "CLONE_PTRACE" }, 489 { CLONE_VFORK, "CLONE_VFORK" }, 490 { CLONE_PARENT, "CLONE_PARENT" }, 491 { 0, NULL }, 492}; 493 494int 495sys_clone(tcp) 496struct tcb *tcp; 497{ 498 if (exiting(tcp)) { 499 tprintf("child_stack=%#lx, flags=", tcp->u_arg[1]); 500 if (printflags(clone_flags, tcp->u_arg[0]) == 0) 501 tprintf("0"); 502 } 503 return 0; 504} 505 506int 507sys_clone2(tcp) 508struct tcb *tcp; 509{ 510 if (exiting(tcp)) { 511 tprintf("child_stack=%#lx, stack_size=%#lx, flags=", 512 tcp->u_arg[1], tcp->u_arg[2]); 513 if (printflags(clone_flags, tcp->u_arg[0]) == 0) 514 tprintf("0"); 515 } 516 return 0; 517} 518 519#endif 520 521int 522sys_fork(tcp) 523struct tcb *tcp; 524{ 525 if (exiting(tcp)) 526 return RVAL_UDECIMAL; 527 return 0; 528} 529 530int 531change_syscall(tcp, new) 532struct tcb *tcp; 533int new; 534{ 535#if defined(LINUX) 536#if defined(I386) 537 /* Attempt to make vfork into fork, which we can follow. */ 538 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0) 539 return -1; 540 return 0; 541#elif defined(X86_64) 542 /* Attempt to make vfork into fork, which we can follow. */ 543 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0) 544 return -1; 545 return 0; 546#elif defined(POWERPC) 547 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R0), new) < 0) 548 return -1; 549#elif defined(S390) || defined(S390X) 550 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */ 551 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0) 552 return -1; 553 return 0; 554#elif defined(M68K) 555 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0) 556 return -1; 557 return 0; 558#elif defined(SPARC) 559 struct regs regs; 560 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0) 561 return -1; 562 regs.r_g1=new; 563 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0) 564 return -1; 565 return 0; 566#elif defined(MIPS) 567 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0) 568 return -1; 569 return 0; 570#elif defined(ALPHA) 571 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0) 572 return -1; 573 return 0; 574#elif defined(IA64) 575 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0) 576 return -1; 577 return 0; 578#elif defined(HPPA) 579 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0) 580 return -1; 581 return 0; 582#elif defined(SH) 583 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0) 584 return -1; 585 return 0; 586#else 587#warning Do not know how to handle change_syscall for this architecture 588#endif /* architecture */ 589#endif /* LINUX */ 590 return -1; 591} 592 593int 594setarg(tcp, argnum) 595 struct tcb *tcp; 596 int argnum; 597{ 598#if defined (IA64) 599 { 600 unsigned long *bsp, *ap; 601 602 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0) 603 return -1; 604 605 ap = ia64_rse_skip_regs(bsp, argnum); 606 errno = 0; 607 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]); 608 if (errno) 609 return -1; 610 611 } 612#elif defined(I386) 613 { 614 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]); 615 if (errno) 616 return -1; 617 } 618#elif defined(X86_64) 619 { 620 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]); 621 if (errno) 622 return -1; 623 } 624#elif defined(POWERPC) 625#ifndef PT_ORIG_R3 626#define PT_ORIG_R3 34 627#endif 628 { 629 ptrace(PTRACE_POKEUSER, tcp->pid, 630 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*4), 631 tcp->u_arg[argnum]); 632 if (errno) 633 return -1; 634 } 635#elif defined(MIPS) 636 { 637 errno = 0; 638 if (argnum < 4) 639 ptrace(PTRACE_POKEUSER, tcp->pid, 640 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]); 641 else { 642 unsigned long *sp; 643 644 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0) 645 return -1; 646 647 ptrace(PTRACE_POKEDATA, tcp->pid, 648 (char*)(sp + argnum - 4), tcp->u_arg[argnum]); 649 } 650 if (errno) 651 return -1; 652 } 653#elif defined(S390) || defined(S390X) 654 { 655 if(argnum <= 5) 656 ptrace(PTRACE_POKEUSER, tcp->pid, 657 (char *) (argnum==0 ? PT_ORIGGPR2 : 658 PT_GPR2 + argnum*sizeof(long)), 659 tcp->u_arg[argnum]); 660 else 661 return -E2BIG; 662 if (errno) 663 return -1; 664 } 665#else 666# warning Sorry, setargs not implemented for this architecture. 667#endif 668 return 0; 669} 670 671#ifdef SYS_clone 672int 673internal_clone(tcp) 674struct tcb *tcp; 675{ 676 struct tcb *tcpchild; 677 int pid; 678 if (entering(tcp)) { 679 if (!followfork) 680 return 0; 681 if (fork_tcb(tcp)) 682 return 0; 683 if (setbpt(tcp) < 0) 684 return 0; 685 } else { 686 int bpt = tcp->flags & TCB_BPTSET; 687 688 if (!(tcp->flags & TCB_FOLLOWFORK)) 689 return 0; 690 691 if (syserror(tcp)) { 692 if (bpt) 693 clearbpt(tcp); 694 return 0; 695 } 696 697 pid = tcp->u_rval; 698 if ((tcpchild = alloctcb(pid)) == NULL) { 699 if (bpt) 700 clearbpt(tcp); 701 fprintf(stderr, " [tcb table full]\n"); 702 kill(pid, SIGKILL); /* XXX */ 703 return 0; 704 } 705 706 /* Attach to the new child */ 707 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) { 708 if (bpt) 709 clearbpt(tcp); 710 perror("PTRACE_ATTACH"); 711 fprintf(stderr, "Too late?\n"); 712 droptcb(tcpchild); 713 return 0; 714 } 715 716 if (bpt) 717 clearbpt(tcp); 718 719 tcpchild->flags |= TCB_ATTACHED; 720 if (bpt) { 721 tcpchild->flags |= TCB_BPTSET; 722 tcpchild->baddr = tcp->baddr; 723 memcpy(tcpchild->inst, tcp->inst, 724 sizeof tcpchild->inst); 725 } 726 newoutf(tcpchild); 727 tcpchild->parent = tcp; 728 tcp->nchildren++; 729 if (!qflag) 730 fprintf(stderr, "Process %d attached\n", pid); 731 } 732 return 0; 733} 734#endif 735 736int 737internal_fork(tcp) 738struct tcb *tcp; 739{ 740 struct tcb *tcpchild; 741 int pid; 742 int dont_follow = 0; 743 744#ifdef SYS_vfork 745 if (tcp->scno == SYS_vfork) { 746 /* Attempt to make vfork into fork, which we can follow. */ 747 if (!followvfork || 748 change_syscall(tcp, SYS_fork) < 0) 749 dont_follow = 1; 750 } 751#endif 752 if (entering(tcp)) { 753 if (!followfork || dont_follow) 754 return 0; 755 if (fork_tcb(tcp)) 756 return 0; 757 if (setbpt(tcp) < 0) 758 return 0; 759 } 760 else { 761 int bpt = tcp->flags & TCB_BPTSET; 762 763 if (!(tcp->flags & TCB_FOLLOWFORK)) 764 return 0; 765 if (bpt) 766 clearbpt(tcp); 767 768 if (syserror(tcp)) 769 return 0; 770 771 pid = tcp->u_rval; 772 if ((tcpchild = alloctcb(pid)) == NULL) { 773 fprintf(stderr, " [tcb table full]\n"); 774 kill(pid, SIGKILL); /* XXX */ 775 return 0; 776 } 777#ifdef LINUX 778#ifdef HPPA 779 /* The child must have run before it can be attached. */ 780 /* This must be a bug in the parisc kernel, but I havn't 781 * identified it yet. Seems to be an issue associated 782 * with attaching to a process (which sends it a signal) 783 * before that process has ever been scheduled. When 784 * debugging, I started seeing crashes in 785 * arch/parisc/kernel/signal.c:do_signal(), apparently 786 * caused by r8 getting corrupt over the dequeue_signal() 787 * call. Didn't make much sense though... 788 */ 789 { 790 struct timeval tv; 791 tv.tv_sec = 0; 792 tv.tv_usec = 10000; 793 select(0, NULL, NULL, NULL, &tv); 794 } 795#endif 796 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) { 797 perror("PTRACE_ATTACH"); 798 fprintf(stderr, "Too late?\n"); 799 droptcb(tcpchild); 800 return 0; 801 } 802#endif /* LINUX */ 803#ifdef SUNOS4 804#ifdef oldway 805 /* The child must have run before it can be attached. */ 806 { 807 struct timeval tv; 808 tv.tv_sec = 0; 809 tv.tv_usec = 10000; 810 select(0, NULL, NULL, NULL, &tv); 811 } 812 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) { 813 perror("PTRACE_ATTACH"); 814 fprintf(stderr, "Too late?\n"); 815 droptcb(tcpchild); 816 return 0; 817 } 818#else /* !oldway */ 819 /* Try to catch the new process as soon as possible. */ 820 { 821 int i; 822 for (i = 0; i < 1024; i++) 823 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0) 824 break; 825 if (i == 1024) { 826 perror("PTRACE_ATTACH"); 827 fprintf(stderr, "Too late?\n"); 828 droptcb(tcpchild); 829 return 0; 830 } 831 } 832#endif /* !oldway */ 833#endif /* SUNOS4 */ 834 tcpchild->flags |= TCB_ATTACHED; 835 /* Child has BPT too, must be removed on first occasion */ 836 if (bpt) { 837 tcpchild->flags |= TCB_BPTSET; 838 tcpchild->baddr = tcp->baddr; 839 memcpy(tcpchild->inst, tcp->inst, 840 sizeof tcpchild->inst); 841 } 842 newoutf(tcpchild); 843 tcpchild->parent = tcp; 844 tcp->nchildren++; 845 if (!qflag) 846 fprintf(stderr, "Process %d attached\n", pid); 847 } 848 return 0; 849} 850 851#endif /* !USE_PROCFS */ 852 853#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD) 854 855int 856sys_vfork(tcp) 857struct tcb *tcp; 858{ 859 if (exiting(tcp)) 860 return RVAL_UDECIMAL; 861 return 0; 862} 863 864#endif /* SUNOS4 || LINUX || FREEBSD */ 865 866#ifndef LINUX 867 868static char idstr[16]; 869 870int 871sys_getpid(tcp) 872struct tcb *tcp; 873{ 874 if (exiting(tcp)) { 875 sprintf(idstr, "ppid %lu", getrval2(tcp)); 876 tcp->auxstr = idstr; 877 return RVAL_STR; 878 } 879 return 0; 880} 881 882int 883sys_getuid(tcp) 884struct tcb *tcp; 885{ 886 if (exiting(tcp)) { 887 sprintf(idstr, "euid %lu", getrval2(tcp)); 888 tcp->auxstr = idstr; 889 return RVAL_STR; 890 } 891 return 0; 892} 893 894int 895sys_getgid(tcp) 896struct tcb *tcp; 897{ 898 if (exiting(tcp)) { 899 sprintf(idstr, "egid %lu", getrval2(tcp)); 900 tcp->auxstr = idstr; 901 return RVAL_STR; 902 } 903 return 0; 904} 905 906#endif /* !LINUX */ 907 908#ifdef LINUX 909 910int 911sys_setuid(tcp) 912struct tcb *tcp; 913{ 914 if (entering(tcp)) { 915 tprintf("%u", (uid_t) tcp->u_arg[0]); 916 } 917 return 0; 918} 919 920int 921sys_setgid(tcp) 922struct tcb *tcp; 923{ 924 if (entering(tcp)) { 925 tprintf("%u", (gid_t) tcp->u_arg[0]); 926 } 927 return 0; 928} 929 930int 931sys_getresuid(tcp) 932 struct tcb *tcp; 933{ 934 if (exiting(tcp)) { 935 __kernel_uid_t uid; 936 if (syserror(tcp)) 937 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0], 938 tcp->u_arg[1], tcp->u_arg[2]); 939 else { 940 if (umove(tcp, tcp->u_arg[0], &uid) < 0) 941 tprintf("%#lx, ", tcp->u_arg[0]); 942 else 943 tprintf("ruid %lu, ", (unsigned long) uid); 944 if (umove(tcp, tcp->u_arg[0], &uid) < 0) 945 tprintf("%#lx, ", tcp->u_arg[0]); 946 else 947 tprintf("euid %lu, ", (unsigned long) uid); 948 if (umove(tcp, tcp->u_arg[0], &uid) < 0) 949 tprintf("%#lx", tcp->u_arg[0]); 950 else 951 tprintf("suid %lu", (unsigned long) uid); 952 } 953 } 954 return 0; 955} 956 957int 958sys_getresgid(tcp) 959struct tcb *tcp; 960{ 961 if (exiting(tcp)) { 962 __kernel_gid_t gid; 963 if (syserror(tcp)) 964 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0], 965 tcp->u_arg[1], tcp->u_arg[2]); 966 else { 967 if (umove(tcp, tcp->u_arg[0], &gid) < 0) 968 tprintf("%#lx, ", tcp->u_arg[0]); 969 else 970 tprintf("rgid %lu, ", (unsigned long) gid); 971 if (umove(tcp, tcp->u_arg[0], &gid) < 0) 972 tprintf("%#lx, ", tcp->u_arg[0]); 973 else 974 tprintf("egid %lu, ", (unsigned long) gid); 975 if (umove(tcp, tcp->u_arg[0], &gid) < 0) 976 tprintf("%#lx", tcp->u_arg[0]); 977 else 978 tprintf("sgid %lu", (unsigned long) gid); 979 } 980 } 981 return 0; 982} 983 984#endif /* LINUX */ 985 986int 987sys_setreuid(tcp) 988struct tcb *tcp; 989{ 990 if (entering(tcp)) { 991 tprintf("%lu, %lu", 992 (unsigned long) (uid_t) tcp->u_arg[0], 993 (unsigned long) (uid_t) tcp->u_arg[1]); 994 } 995 return 0; 996} 997 998int 999sys_setregid(tcp) 1000struct tcb *tcp; 1001{ 1002 if (entering(tcp)) { 1003 tprintf("%lu, %lu", 1004 (unsigned long) (gid_t) tcp->u_arg[0], 1005 (unsigned long) (gid_t) tcp->u_arg[1]); 1006 } 1007 return 0; 1008} 1009 1010#if defined(LINUX) || defined(FREEBSD) 1011int 1012sys_setresuid(tcp) 1013 struct tcb *tcp; 1014{ 1015 if (entering(tcp)) { 1016 tprintf("ruid %u, euid %u, suid %u", 1017 (uid_t) tcp->u_arg[0], 1018 (uid_t) tcp->u_arg[1], 1019 (uid_t) tcp->u_arg[2]); 1020 } 1021 return 0; 1022} 1023int 1024sys_setresgid(tcp) 1025 struct tcb *tcp; 1026{ 1027 if (entering(tcp)) { 1028 tprintf("rgid %u, egid %u, sgid %u", 1029 (uid_t) tcp->u_arg[0], 1030 (uid_t) tcp->u_arg[1], 1031 (uid_t) tcp->u_arg[2]); 1032 } 1033 return 0; 1034} 1035 1036#endif /* LINUX || FREEBSD */ 1037 1038int 1039sys_setgroups(tcp) 1040struct tcb *tcp; 1041{ 1042 int i, len; 1043 GETGROUPS_T *gidset; 1044 1045 if (entering(tcp)) { 1046 len = tcp->u_arg[0]; 1047 tprintf("%u, ", len); 1048 if (len <= 0) { 1049 tprintf("[]"); 1050 return 0; 1051 } 1052 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T)); 1053 if (gidset == NULL) { 1054 fprintf(stderr, "sys_setgroups: out of memory\n"); 1055 return -1; 1056 } 1057 if (!verbose(tcp)) 1058 tprintf("%#lx", tcp->u_arg[1]); 1059 else if (umoven(tcp, tcp->u_arg[1], 1060 len * sizeof(GETGROUPS_T), (char *) gidset) < 0) 1061 tprintf("[?]"); 1062 else { 1063 tprintf("["); 1064 for (i = 0; i < len; i++) 1065 tprintf("%s%lu", i ? ", " : "", 1066 (unsigned long) gidset[i]); 1067 tprintf("]"); 1068 } 1069 free((char *) gidset); 1070 } 1071 return 0; 1072} 1073 1074int 1075sys_getgroups(tcp) 1076struct tcb *tcp; 1077{ 1078 int i, len; 1079 GETGROUPS_T *gidset; 1080 1081 if (entering(tcp)) { 1082 len = tcp->u_arg[0]; 1083 tprintf("%u, ", len); 1084 } else { 1085 len = tcp->u_rval; 1086 if (len <= 0) { 1087 tprintf("[]"); 1088 return 0; 1089 } 1090 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T)); 1091 if (gidset == NULL) { 1092 fprintf(stderr, "sys_getgroups: out of memory\n"); 1093 return -1; 1094 } 1095 if (!tcp->u_arg[1]) 1096 tprintf("NULL"); 1097 else if (!verbose(tcp) || tcp->u_arg[0] == 0) 1098 tprintf("%#lx", tcp->u_arg[1]); 1099 else if (umoven(tcp, tcp->u_arg[1], 1100 len * sizeof(GETGROUPS_T), (char *) gidset) < 0) 1101 tprintf("[?]"); 1102 else { 1103 tprintf("["); 1104 for (i = 0; i < len; i++) 1105 tprintf("%s%lu", i ? ", " : "", 1106 (unsigned long) gidset[i]); 1107 tprintf("]"); 1108 } 1109 free((char *)gidset); 1110 } 1111 return 0; 1112} 1113 1114int 1115sys_setpgrp(tcp) 1116struct tcb *tcp; 1117{ 1118 if (entering(tcp)) { 1119#ifndef SVR4 1120 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]); 1121#endif /* !SVR4 */ 1122 } 1123 return 0; 1124} 1125 1126int 1127sys_getpgrp(tcp) 1128struct tcb *tcp; 1129{ 1130 if (entering(tcp)) { 1131#ifndef SVR4 1132 tprintf("%lu", tcp->u_arg[0]); 1133#endif /* !SVR4 */ 1134 } 1135 return 0; 1136} 1137 1138int 1139sys_getsid(tcp) 1140struct tcb *tcp; 1141{ 1142 if (entering(tcp)) { 1143 tprintf("%lu", tcp->u_arg[0]); 1144 } 1145 return 0; 1146} 1147 1148int 1149sys_setsid(tcp) 1150struct tcb *tcp; 1151{ 1152 return 0; 1153} 1154 1155int 1156sys_getpgid(tcp) 1157struct tcb *tcp; 1158{ 1159 if (entering(tcp)) { 1160 tprintf("%lu", tcp->u_arg[0]); 1161 } 1162 return 0; 1163} 1164 1165int 1166sys_setpgid(tcp) 1167struct tcb *tcp; 1168{ 1169 if (entering(tcp)) { 1170 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]); 1171 } 1172 return 0; 1173} 1174 1175#if UNIXWARE >= 2 1176 1177#include <sys/privilege.h> 1178 1179 1180static struct xlat procpriv_cmds [] = { 1181 { SETPRV, "SETPRV" }, 1182 { CLRPRV, "CLRPRV" }, 1183 { PUTPRV, "PUTPRV" }, 1184 { GETPRV, "GETPRV" }, 1185 { CNTPRV, "CNTPRV" }, 1186 { 0, NULL }, 1187}; 1188 1189 1190static struct xlat procpriv_priv [] = { 1191 { P_OWNER, "P_OWNER" }, 1192 { P_AUDIT, "P_AUDIT" }, 1193 { P_COMPAT, "P_COMPAT" }, 1194 { P_DACREAD, "P_DACREAD" }, 1195 { P_DACWRITE, "P_DACWRITE" }, 1196 { P_DEV, "P_DEV" }, 1197 { P_FILESYS, "P_FILESYS" }, 1198 { P_MACREAD, "P_MACREAD" }, 1199 { P_MACWRITE, "P_MACWRITE" }, 1200 { P_MOUNT, "P_MOUNT" }, 1201 { P_MULTIDIR, "P_MULTIDIR" }, 1202 { P_SETPLEVEL, "P_SETPLEVEL" }, 1203 { P_SETSPRIV, "P_SETSPRIV" }, 1204 { P_SETUID, "P_SETUID" }, 1205 { P_SYSOPS, "P_SYSOPS" }, 1206 { P_SETUPRIV, "P_SETUPRIV" }, 1207 { P_DRIVER, "P_DRIVER" }, 1208 { P_RTIME, "P_RTIME" }, 1209 { P_MACUPGRADE, "P_MACUPGRADE" }, 1210 { P_FSYSRANGE, "P_FSYSRANGE" }, 1211 { P_SETFLEVEL, "P_SETFLEVEL" }, 1212 { P_AUDITWR, "P_AUDITWR" }, 1213 { P_TSHAR, "P_TSHAR" }, 1214 { P_PLOCK, "P_PLOCK" }, 1215 { P_CORE, "P_CORE" }, 1216 { P_LOADMOD, "P_LOADMOD" }, 1217 { P_BIND, "P_BIND" }, 1218 { P_ALLPRIVS, "P_ALLPRIVS" }, 1219 { 0, NULL }, 1220}; 1221 1222 1223static struct xlat procpriv_type [] = { 1224 { PS_FIX, "PS_FIX" }, 1225 { PS_INH, "PS_INH" }, 1226 { PS_MAX, "PS_MAX" }, 1227 { PS_WKG, "PS_WKG" }, 1228 { 0, NULL }, 1229}; 1230 1231 1232static void 1233printpriv(tcp, addr, len, opt) 1234struct tcb *tcp; 1235long addr; 1236int len; 1237struct xlat *opt; 1238{ 1239 priv_t buf [128]; 1240 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10; 1241 int dots = len > max; 1242 int i; 1243 1244 if (len > max) len = max; 1245 1246 if (len <= 0 || 1247 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0) 1248 { 1249 tprintf ("%#lx", addr); 1250 return; 1251 } 1252 1253 tprintf ("["); 1254 1255 for (i = 0; i < len; ++i) { 1256 char *t, *p; 1257 1258 if (i) tprintf (", "); 1259 1260 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) && 1261 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE))) 1262 { 1263 tprintf ("%s|%s", t, p); 1264 } 1265 else { 1266 tprintf ("%#lx", buf [i]); 1267 } 1268 } 1269 1270 if (dots) tprintf (" ..."); 1271 1272 tprintf ("]"); 1273} 1274 1275 1276int 1277sys_procpriv(tcp) 1278struct tcb *tcp; 1279{ 1280 if (entering(tcp)) { 1281 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV"); 1282 switch (tcp->u_arg[0]) { 1283 case CNTPRV: 1284 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]); 1285 break; 1286 1287 case GETPRV: 1288 break; 1289 1290 default: 1291 tprintf (", "); 1292 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]); 1293 tprintf (", %ld", tcp->u_arg[2]); 1294 } 1295 } 1296 else if (tcp->u_arg[0] == GETPRV) { 1297 if (syserror (tcp)) { 1298 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]); 1299 } 1300 else { 1301 tprintf (", "); 1302 printpriv (tcp, tcp->u_arg[1], tcp->u_rval); 1303 tprintf (", %ld", tcp->u_arg[2]); 1304 } 1305 } 1306 1307 return 0; 1308} 1309 1310#endif 1311 1312 1313void 1314fake_execve(tcp, program, argv, envp) 1315struct tcb *tcp; 1316char *program; 1317char *argv[]; 1318char *envp[]; 1319{ 1320 int i; 1321 1322#ifdef ARM 1323 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE)) 1324 return; 1325#else 1326 if (!(qual_flags[SYS_execve] & QUAL_TRACE)) 1327 return; 1328#endif /* !ARM */ 1329 printleader(tcp); 1330 tprintf("execve("); 1331 string_quote(program); 1332 tprintf(", ["); 1333 for (i = 0; argv[i] != NULL; i++) { 1334 if (i != 0) 1335 tprintf(", "); 1336 string_quote(argv[i]); 1337 } 1338 for (i = 0; envp[i] != NULL; i++) 1339 ; 1340 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : ""); 1341 tabto(acolumn); 1342 tprintf("= 0"); 1343 printtrailer(tcp); 1344} 1345 1346static void 1347printargv(tcp, addr) 1348struct tcb *tcp; 1349long addr; 1350{ 1351 char *cp; 1352 char *sep; 1353 int max = max_strlen / 2; 1354 1355 for (sep = ""; --max >= 0; sep = ", ") { 1356 if (!abbrev(tcp)) 1357 max++; 1358 if (umove(tcp, addr, &cp) < 0) { 1359 tprintf("%#lx", addr); 1360 return; 1361 } 1362 if (cp == 0) 1363 break; 1364 tprintf(sep); 1365 printstr(tcp, (long) cp, -1); 1366 addr += sizeof(char *); 1367 } 1368 if (cp) 1369 tprintf(", ..."); 1370} 1371 1372static void 1373printargc(fmt, tcp, addr) 1374char *fmt; 1375struct tcb *tcp; 1376long addr; 1377{ 1378 int count; 1379 char *cp; 1380 1381 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) { 1382 addr += sizeof(char *); 1383 } 1384 tprintf(fmt, count, count == 1 ? "" : "s"); 1385} 1386 1387int 1388sys_execv(tcp) 1389struct tcb *tcp; 1390{ 1391 if (entering(tcp)) { 1392 printpath(tcp, tcp->u_arg[0]); 1393 if (!verbose(tcp)) 1394 tprintf(", %#lx", tcp->u_arg[1]); 1395#if 0 1396 else if (abbrev(tcp)) 1397 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]); 1398#endif 1399 else { 1400 tprintf(", ["); 1401 printargv(tcp, tcp->u_arg[1]); 1402 tprintf("]"); 1403 } 1404 } 1405 return 0; 1406} 1407 1408int 1409sys_execve(tcp) 1410struct tcb *tcp; 1411{ 1412 if (entering(tcp)) { 1413 printpath(tcp, tcp->u_arg[0]); 1414 if (!verbose(tcp)) 1415 tprintf(", %#lx", tcp->u_arg[1]); 1416#if 0 1417 else if (abbrev(tcp)) 1418 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]); 1419#endif 1420 else { 1421 tprintf(", ["); 1422 printargv(tcp, tcp->u_arg[1]); 1423 tprintf("]"); 1424 } 1425 if (!verbose(tcp)) 1426 tprintf(", %#lx", tcp->u_arg[2]); 1427 else if (abbrev(tcp)) 1428 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]); 1429 else { 1430 tprintf(", ["); 1431 printargv(tcp, tcp->u_arg[2]); 1432 tprintf("]"); 1433 } 1434 } 1435#ifdef LINUX 1436#if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) 1437 tcp->flags |= TCB_WAITEXECVE; 1438#endif /* ALPHA || SPARC || POWERPC || IA64 || HPPA || SH */ 1439#endif /* LINUX */ 1440 return 0; 1441} 1442 1443#if UNIXWARE > 2 1444 1445int sys_rexecve(tcp) 1446struct tcb *tcp; 1447{ 1448 if (entering (tcp)) { 1449 sys_execve (tcp); 1450 tprintf (", %ld", tcp->u_arg[3]); 1451 } 1452 return 0; 1453} 1454 1455#endif 1456 1457int 1458internal_exec(tcp) 1459struct tcb *tcp; 1460{ 1461#ifdef SUNOS4 1462 if (exiting(tcp) && !syserror(tcp) && followfork) 1463 fixvfork(tcp); 1464#endif /* SUNOS4 */ 1465 return 0; 1466} 1467 1468#ifdef LINUX 1469#ifndef __WNOTHREAD 1470#define __WNOTHREAD 0x20000000 1471#endif 1472#ifndef __WALL 1473#define __WALL 0x40000000 1474#endif 1475#ifndef __WCLONE 1476#define __WCLONE 0x80000000 1477#endif 1478#endif /* LINUX */ 1479 1480static struct xlat wait4_options[] = { 1481 { WNOHANG, "WNOHANG" }, 1482#ifndef WSTOPPED 1483 { WUNTRACED, "WUNTRACED" }, 1484#endif 1485#ifdef WEXITED 1486 { WEXITED, "WEXITED" }, 1487#endif 1488#ifdef WTRAPPED 1489 { WTRAPPED, "WTRAPPED" }, 1490#endif 1491#ifdef WSTOPPED 1492 { WSTOPPED, "WSTOPPED" }, 1493#endif 1494#ifdef WCONTINUED 1495 { WCONTINUED, "WCONTINUED" }, 1496#endif 1497#ifdef WNOWAIT 1498 { WNOWAIT, "WNOWAIT" }, 1499#endif 1500#ifdef __WCLONE 1501 { __WCLONE, "__WCLONE" }, 1502#endif 1503#ifdef __WALL 1504 { __WALL, "__WALL" }, 1505#endif 1506#ifdef __WNOTHREAD 1507 { __WNOTHREAD, "__WNOTHREAD" }, 1508#endif 1509 { 0, NULL }, 1510}; 1511 1512static int 1513printstatus(status) 1514int status; 1515{ 1516 int exited = 0; 1517 1518 /* 1519 * Here is a tricky presentation problem. This solution 1520 * is still not entirely satisfactory but since there 1521 * are no wait status constructors it will have to do. 1522 */ 1523 if (WIFSTOPPED(status)) 1524 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]", 1525 signame(WSTOPSIG(status))); 1526 else if WIFSIGNALED(status) 1527 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]", 1528 signame(WTERMSIG(status)), 1529 WCOREDUMP(status) ? " && WCOREDUMP(s)" : ""); 1530 else if WIFEXITED(status) { 1531 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]", 1532 WEXITSTATUS(status)); 1533 exited = 1; 1534 } 1535 else 1536 tprintf("[%#x]", status); 1537 return exited; 1538} 1539 1540static int 1541printwaitn(tcp, n, bitness) 1542struct tcb *tcp; 1543int n; 1544int bitness; 1545{ 1546 int status; 1547 int exited = 0; 1548 1549 if (entering(tcp)) { 1550 tprintf("%ld, ", tcp->u_arg[0]); 1551 } else { 1552 /* status */ 1553 if (!tcp->u_arg[1]) 1554 tprintf("NULL"); 1555 else if (syserror(tcp) || tcp->u_rval == 0) 1556 tprintf("%#lx", tcp->u_arg[1]); 1557 else if (umove(tcp, tcp->u_arg[1], &status) < 0) 1558 tprintf("[?]"); 1559 else 1560 exited = printstatus(status); 1561 /* options */ 1562 tprintf(", "); 1563 if (!printflags(wait4_options, tcp->u_arg[2])) 1564 tprintf("0"); 1565 if (n == 4) { 1566 tprintf(", "); 1567 /* usage */ 1568 if (!tcp->u_arg[3]) 1569 tprintf("NULL"); 1570#ifdef LINUX 1571 else if (tcp->u_rval > 0) { 1572#ifdef LINUX_64BIT 1573 if (bitness) 1574 printrusage32(tcp, tcp->u_arg[3]); 1575 else 1576#endif 1577 printrusage(tcp, tcp->u_arg[3]); 1578 } 1579#endif /* LINUX */ 1580#ifdef SUNOS4 1581 else if (tcp->u_rval > 0 && exited) 1582 printrusage(tcp, tcp->u_arg[3]); 1583#endif /* SUNOS4 */ 1584 else 1585 tprintf("%#lx", tcp->u_arg[3]); 1586 } 1587 } 1588 return 0; 1589} 1590 1591int 1592internal_wait(tcp) 1593struct tcb *tcp; 1594{ 1595 if (entering(tcp) && tcp->nchildren > 0) { 1596 /* There are children that this parent should block for. 1597 But ptrace made us the parent of the traced children 1598 and the real parent will get ECHILD from the wait call. 1599 1600 XXX If we attached with strace -f -p PID, then there 1601 may be untraced dead children the parent could be reaping 1602 now, but we make him block. */ 1603 1604 /* ??? WTA: fix bug with hanging children */ 1605 1606 if (!(tcp->u_arg[2] & WNOHANG)) { 1607 /* There are traced children */ 1608 tcp->flags |= TCB_SUSPENDED; 1609 tcp->waitpid = tcp->u_arg[0]; 1610 } 1611 } 1612 if (exiting(tcp) && tcp->u_error == ECHILD && tcp->nchildren > 0) { 1613 if (tcp->u_arg[2] & WNOHANG) { 1614 /* We must force a fake result of 0 instead of 1615 the ECHILD error. */ 1616 extern int force_result(); 1617 return force_result(tcp, 0, 0); 1618 } 1619 else 1620 fprintf(stderr, 1621 "internal_wait: should not have resumed %d\n", 1622 tcp->pid); 1623 } 1624 return 0; 1625} 1626 1627#ifdef SVR4 1628 1629int 1630sys_wait(tcp) 1631struct tcb *tcp; 1632{ 1633 if (exiting(tcp)) { 1634 /* The library wrapper stuffs this into the user variable. */ 1635 if (!syserror(tcp)) 1636 printstatus(getrval2(tcp)); 1637 } 1638 return 0; 1639} 1640 1641#endif /* SVR4 */ 1642 1643#ifdef FREEBSD 1644int 1645sys_wait(tcp) 1646struct tcb *tcp; 1647{ 1648 int status; 1649 1650 if (exiting(tcp)) { 1651 if (!syserror(tcp)) { 1652 if (umove(tcp, tcp->u_arg[0], &status) < 0) 1653 tprintf("%#lx", tcp->u_arg[0]); 1654 else 1655 printstatus(status); 1656 } 1657 } 1658 return 0; 1659} 1660#endif 1661 1662int 1663sys_waitpid(tcp) 1664struct tcb *tcp; 1665{ 1666 return printwaitn(tcp, 3, 0); 1667} 1668 1669int 1670sys_wait4(tcp) 1671struct tcb *tcp; 1672{ 1673 return printwaitn(tcp, 4, 0); 1674} 1675 1676#ifdef ALPHA 1677int 1678sys_osf_wait4(tcp) 1679struct tcb *tcp; 1680{ 1681 return printwaitn(tcp, 4, 1); 1682} 1683#endif 1684 1685#ifdef SVR4 1686 1687static struct xlat waitid_types[] = { 1688 { P_PID, "P_PID" }, 1689 { P_PPID, "P_PPID" }, 1690 { P_PGID, "P_PGID" }, 1691 { P_SID, "P_SID" }, 1692 { P_CID, "P_CID" }, 1693 { P_UID, "P_UID" }, 1694 { P_GID, "P_GID" }, 1695 { P_ALL, "P_ALL" }, 1696#ifdef P_LWPID 1697 { P_LWPID, "P_LWPID" }, 1698#endif 1699 { 0, NULL }, 1700}; 1701 1702int 1703sys_waitid(tcp) 1704struct tcb *tcp; 1705{ 1706 siginfo_t si; 1707 int exited; 1708 1709 if (entering(tcp)) { 1710 printxval(waitid_types, tcp->u_arg[0], "P_???"); 1711 tprintf(", %ld, ", tcp->u_arg[1]); 1712 if (tcp->nchildren > 0) { 1713 /* There are traced children */ 1714 tcp->flags |= TCB_SUSPENDED; 1715 tcp->waitpid = tcp->u_arg[0]; 1716 } 1717 } 1718 else { 1719 /* siginfo */ 1720 exited = 0; 1721 if (!tcp->u_arg[2]) 1722 tprintf("NULL"); 1723 else if (syserror(tcp)) 1724 tprintf("%#lx", tcp->u_arg[2]); 1725 else if (umove(tcp, tcp->u_arg[2], &si) < 0) 1726 tprintf("{???}"); 1727 else 1728 printsiginfo(&si, verbose (tcp)); 1729 /* options */ 1730 tprintf(", "); 1731 if (!printflags(wait4_options, tcp->u_arg[3])) 1732 tprintf("0"); 1733 } 1734 return 0; 1735} 1736 1737#endif /* SVR4 */ 1738 1739int 1740sys_alarm(tcp) 1741struct tcb *tcp; 1742{ 1743 if (entering(tcp)) 1744 tprintf("%lu", tcp->u_arg[0]); 1745 return 0; 1746} 1747 1748int 1749sys_uname(tcp) 1750struct tcb *tcp; 1751{ 1752 struct utsname uname; 1753 1754 if (exiting(tcp)) { 1755 if (syserror(tcp) || !verbose(tcp)) 1756 tprintf("%#lx", tcp->u_arg[0]); 1757 else if (umove(tcp, tcp->u_arg[0], &uname) < 0) 1758 tprintf("{...}"); 1759 else if (!abbrev(tcp)) { 1760 1761 tprintf("{sysname=\"%s\", nodename=\"%s\", ", 1762 uname.sysname, uname.nodename); 1763 tprintf("release=\"%s\", version=\"%s\", ", 1764 uname.release, uname.version); 1765 tprintf("machine=\"%s\"", uname.machine); 1766#ifdef LINUX 1767#ifndef __GLIBC__ 1768 tprintf(", domainname=\"%s\"", uname.domainname); 1769#endif /* __GLIBC__ */ 1770#endif /* LINUX */ 1771 tprintf("}"); 1772 } 1773 else 1774 tprintf("{sys=\"%s\", node=\"%s\", ...}", 1775 uname.sysname, uname.nodename); 1776 } 1777 return 0; 1778} 1779 1780#ifndef SVR4 1781 1782static struct xlat ptrace_cmds[] = { 1783#ifndef FREEBSD 1784 { PTRACE_TRACEME, "PTRACE_TRACEME" }, 1785 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", }, 1786 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", }, 1787 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", }, 1788 { PTRACE_POKETEXT, "PTRACE_POKETEXT", }, 1789 { PTRACE_POKEDATA, "PTRACE_POKEDATA", }, 1790 { PTRACE_POKEUSER, "PTRACE_POKEUSER", }, 1791 { PTRACE_CONT, "PTRACE_CONT" }, 1792 { PTRACE_KILL, "PTRACE_KILL" }, 1793 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" }, 1794 { PTRACE_ATTACH, "PTRACE_ATTACH" }, 1795 { PTRACE_DETACH, "PTRACE_DETACH" }, 1796#ifdef SUNOS4 1797 { PTRACE_GETREGS, "PTRACE_GETREGS" }, 1798 { PTRACE_SETREGS, "PTRACE_SETREGS" }, 1799 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", }, 1800 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", }, 1801 { PTRACE_READDATA, "PTRACE_READDATA" }, 1802 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" }, 1803 { PTRACE_READTEXT, "PTRACE_READTEXT" }, 1804 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" }, 1805 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" }, 1806 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" }, 1807#ifdef SPARC 1808 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" }, 1809 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" }, 1810#else /* !SPARC */ 1811 { PTRACE_22, "PTRACE_PTRACE_22" }, 1812 { PTRACE_23, "PTRACE_PTRACE_23" }, 1813#endif /* !SPARC */ 1814#endif /* SUNOS4 */ 1815 { PTRACE_SYSCALL, "PTRACE_SYSCALL" }, 1816#ifdef SUNOS4 1817 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" }, 1818#ifdef I386 1819 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" }, 1820 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" }, 1821 { PTRACE_CLRDR7, "PTRACE_CLRDR7" }, 1822#else /* !I386 */ 1823 { PTRACE_26, "PTRACE_26" }, 1824 { PTRACE_27, "PTRACE_27" }, 1825 { PTRACE_28, "PTRACE_28" }, 1826#endif /* !I386 */ 1827 { PTRACE_GETUCODE, "PTRACE_GETUCODE" }, 1828#endif /* SUNOS4 */ 1829#else /* FREEBSD */ 1830 { PT_TRACE_ME, "PT_TRACE_ME" }, 1831 { PT_READ_I, "PT_READ_I" }, 1832 { PT_READ_D, "PT_READ_D" }, 1833 { PT_WRITE_I, "PT_WRITE_I" }, 1834 { PT_WRITE_D, "PT_WRITE_D" }, 1835#ifdef PT_READ_U 1836 { PT_READ_U, "PT_READ_U" }, 1837#endif 1838 { PT_CONTINUE, "PT_CONTINUE" }, 1839 { PT_KILL, "PT_KILL" }, 1840 { PT_STEP, "PT_STEP" }, 1841 { PT_ATTACH, "PT_ATTACH" }, 1842 { PT_DETACH, "PT_DETACH" }, 1843 { PT_GETREGS, "PT_GETREGS" }, 1844 { PT_SETREGS, "PT_SETREGS" }, 1845 { PT_GETFPREGS, "PT_GETFPREGS" }, 1846 { PT_SETFPREGS, "PT_SETFPREGS" }, 1847 { PT_GETDBREGS, "PT_GETDBREGS" }, 1848 { PT_SETDBREGS, "PT_SETDBREGS" }, 1849#endif /* FREEBSD */ 1850 { 0, NULL }, 1851}; 1852 1853#ifndef FREEBSD 1854#ifndef SUNOS4_KERNEL_ARCH_KLUDGE 1855static 1856#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */ 1857struct xlat struct_user_offsets[] = { 1858#ifdef LINUX 1859#if defined(S390) || defined(S390X) 1860 { PT_PSWMASK, "psw_mask" }, 1861 { PT_PSWADDR, "psw_addr" }, 1862 { PT_GPR0, "gpr0" }, 1863 { PT_GPR1, "gpr1" }, 1864 { PT_GPR2, "gpr2" }, 1865 { PT_GPR3, "gpr3" }, 1866 { PT_GPR4, "gpr4" }, 1867 { PT_GPR5, "gpr5" }, 1868 { PT_GPR6, "gpr6" }, 1869 { PT_GPR7, "gpr7" }, 1870 { PT_GPR8, "gpr8" }, 1871 { PT_GPR9, "gpr9" }, 1872 { PT_GPR10, "gpr10" }, 1873 { PT_GPR11, "gpr11" }, 1874 { PT_GPR12, "gpr12" }, 1875 { PT_GPR13, "gpr13" }, 1876 { PT_GPR14, "gpr14" }, 1877 { PT_GPR15, "gpr15" }, 1878 { PT_ACR0, "acr0" }, 1879 { PT_ACR1, "acr1" }, 1880 { PT_ACR2, "acr2" }, 1881 { PT_ACR3, "acr3" }, 1882 { PT_ACR4, "acr4" }, 1883 { PT_ACR5, "acr5" }, 1884 { PT_ACR6, "acr6" }, 1885 { PT_ACR7, "acr7" }, 1886 { PT_ACR8, "acr8" }, 1887 { PT_ACR9, "acr9" }, 1888 { PT_ACR10, "acr10" }, 1889 { PT_ACR11, "acr11" }, 1890 { PT_ACR12, "acr12" }, 1891 { PT_ACR13, "acr13" }, 1892 { PT_ACR14, "acr14" }, 1893 { PT_ACR15, "acr15" }, 1894 { PT_ORIGGPR2, "orig_gpr2" }, 1895 { PT_FPC, "fpc" }, 1896#if defined(S390) 1897 { PT_FPR0_HI, "fpr0.hi" }, 1898 { PT_FPR0_LO, "fpr0.lo" }, 1899 { PT_FPR1_HI, "fpr1.hi" }, 1900 { PT_FPR1_LO, "fpr1.lo" }, 1901 { PT_FPR2_HI, "fpr2.hi" }, 1902 { PT_FPR2_LO, "fpr2.lo" }, 1903 { PT_FPR3_HI, "fpr3.hi" }, 1904 { PT_FPR3_LO, "fpr3.lo" }, 1905 { PT_FPR4_HI, "fpr4.hi" }, 1906 { PT_FPR4_LO, "fpr4.lo" }, 1907 { PT_FPR5_HI, "fpr5.hi" }, 1908 { PT_FPR5_LO, "fpr5.lo" }, 1909 { PT_FPR6_HI, "fpr6.hi" }, 1910 { PT_FPR6_LO, "fpr6.lo" }, 1911 { PT_FPR7_HI, "fpr7.hi" }, 1912 { PT_FPR7_LO, "fpr7.lo" }, 1913 { PT_FPR8_HI, "fpr8.hi" }, 1914 { PT_FPR8_LO, "fpr8.lo" }, 1915 { PT_FPR9_HI, "fpr9.hi" }, 1916 { PT_FPR9_LO, "fpr9.lo" }, 1917 { PT_FPR10_HI, "fpr10.hi" }, 1918 { PT_FPR10_LO, "fpr10.lo" }, 1919 { PT_FPR11_HI, "fpr11.hi" }, 1920 { PT_FPR11_LO, "fpr11.lo" }, 1921 { PT_FPR12_HI, "fpr12.hi" }, 1922 { PT_FPR12_LO, "fpr12.lo" }, 1923 { PT_FPR13_HI, "fpr13.hi" }, 1924 { PT_FPR13_LO, "fpr13.lo" }, 1925 { PT_FPR14_HI, "fpr14.hi" }, 1926 { PT_FPR14_LO, "fpr14.lo" }, 1927 { PT_FPR15_HI, "fpr15.hi" }, 1928 { PT_FPR15_LO, "fpr15.lo" }, 1929#endif 1930#if defined(S390X) 1931 { PT_FPR0, "fpr0" }, 1932 { PT_FPR1, "fpr1" }, 1933 { PT_FPR2, "fpr2" }, 1934 { PT_FPR3, "fpr3" }, 1935 { PT_FPR4, "fpr4" }, 1936 { PT_FPR5, "fpr5" }, 1937 { PT_FPR6, "fpr6" }, 1938 { PT_FPR7, "fpr7" }, 1939 { PT_FPR8, "fpr8" }, 1940 { PT_FPR9, "fpr9" }, 1941 { PT_FPR10, "fpr10" }, 1942 { PT_FPR11, "fpr11" }, 1943 { PT_FPR12, "fpr12" }, 1944 { PT_FPR13, "fpr13" }, 1945 { PT_FPR14, "fpr14" }, 1946 { PT_FPR15, "fpr15" }, 1947#endif 1948 { PT_CR_9, "cr9" }, 1949 { PT_CR_10, "cr10" }, 1950 { PT_CR_11, "cr11" }, 1951 { PT_IEEE_IP, "ieee_exception_ip" }, 1952#endif 1953#if defined(SPARC) 1954 /* XXX No support for these offsets yet. */ 1955#elif defined(HPPA) 1956 /* XXX No support for these offsets yet. */ 1957#elif defined(POWERPC) 1958#ifndef PT_ORIG_R3 1959#define PT_ORIG_R3 34 1960#endif 1961 { 4*PT_R0, "4*PT_R0" }, 1962 { 4*PT_R1, "4*PT_R1" }, 1963 { 4*PT_R2, "4*PT_R2" }, 1964 { 4*PT_R3, "4*PT_R3" }, 1965 { 4*PT_R4, "4*PT_R4" }, 1966 { 4*PT_R5, "4*PT_R5" }, 1967 { 4*PT_R6, "4*PT_R6" }, 1968 { 4*PT_R7, "4*PT_R7" }, 1969 { 4*PT_R8, "4*PT_R8" }, 1970 { 4*PT_R9, "4*PT_R9" }, 1971 { 4*PT_R10, "4*PT_R10" }, 1972 { 4*PT_R11, "4*PT_R11" }, 1973 { 4*PT_R12, "4*PT_R12" }, 1974 { 4*PT_R13, "4*PT_R13" }, 1975 { 4*PT_R14, "4*PT_R14" }, 1976 { 4*PT_R15, "4*PT_R15" }, 1977 { 4*PT_R16, "4*PT_R16" }, 1978 { 4*PT_R17, "4*PT_R17" }, 1979 { 4*PT_R18, "4*PT_R18" }, 1980 { 4*PT_R19, "4*PT_R19" }, 1981 { 4*PT_R20, "4*PT_R20" }, 1982 { 4*PT_R21, "4*PT_R21" }, 1983 { 4*PT_R22, "4*PT_R22" }, 1984 { 4*PT_R23, "4*PT_R23" }, 1985 { 4*PT_R24, "4*PT_R24" }, 1986 { 4*PT_R25, "4*PT_R25" }, 1987 { 4*PT_R26, "4*PT_R26" }, 1988 { 4*PT_R27, "4*PT_R27" }, 1989 { 4*PT_R28, "4*PT_R28" }, 1990 { 4*PT_R29, "4*PT_R29" }, 1991 { 4*PT_R30, "4*PT_R30" }, 1992 { 4*PT_R31, "4*PT_R31" }, 1993 { 4*PT_NIP, "4*PT_NIP" }, 1994 { 4*PT_MSR, "4*PT_MSR" }, 1995 { 4*PT_ORIG_R3, "4*PT_ORIG_R3" }, 1996 { 4*PT_CTR, "4*PT_CTR" }, 1997 { 4*PT_LNK, "4*PT_LNK" }, 1998 { 4*PT_XER, "4*PT_XER" }, 1999 { 4*PT_CCR, "4*PT_CCR" }, 2000 { 4*PT_FPR0, "4*PT_FPR0" }, 2001#else 2002#ifdef ALPHA 2003 { 0, "r0" }, 2004 { 1, "r1" }, 2005 { 2, "r2" }, 2006 { 3, "r3" }, 2007 { 4, "r4" }, 2008 { 5, "r5" }, 2009 { 6, "r6" }, 2010 { 7, "r7" }, 2011 { 8, "r8" }, 2012 { 9, "r9" }, 2013 { 10, "r10" }, 2014 { 11, "r11" }, 2015 { 12, "r12" }, 2016 { 13, "r13" }, 2017 { 14, "r14" }, 2018 { 15, "r15" }, 2019 { 16, "r16" }, 2020 { 17, "r17" }, 2021 { 18, "r18" }, 2022 { 19, "r19" }, 2023 { 20, "r20" }, 2024 { 21, "r21" }, 2025 { 22, "r22" }, 2026 { 23, "r23" }, 2027 { 24, "r24" }, 2028 { 25, "r25" }, 2029 { 26, "r26" }, 2030 { 27, "r27" }, 2031 { 28, "r28" }, 2032 { 29, "gp" }, 2033 { 30, "fp" }, 2034 { 31, "zero" }, 2035 { 32, "fp0" }, 2036 { 33, "fp" }, 2037 { 34, "fp2" }, 2038 { 35, "fp3" }, 2039 { 36, "fp4" }, 2040 { 37, "fp5" }, 2041 { 38, "fp6" }, 2042 { 39, "fp7" }, 2043 { 40, "fp8" }, 2044 { 41, "fp9" }, 2045 { 42, "fp10" }, 2046 { 43, "fp11" }, 2047 { 44, "fp12" }, 2048 { 45, "fp13" }, 2049 { 46, "fp14" }, 2050 { 47, "fp15" }, 2051 { 48, "fp16" }, 2052 { 49, "fp17" }, 2053 { 50, "fp18" }, 2054 { 51, "fp19" }, 2055 { 52, "fp20" }, 2056 { 53, "fp21" }, 2057 { 54, "fp22" }, 2058 { 55, "fp23" }, 2059 { 56, "fp24" }, 2060 { 57, "fp25" }, 2061 { 58, "fp26" }, 2062 { 59, "fp27" }, 2063 { 60, "fp28" }, 2064 { 61, "fp29" }, 2065 { 62, "fp30" }, 2066 { 63, "fp31" }, 2067 { 64, "pc" }, 2068#else /* !ALPHA */ 2069#ifdef IA64 2070 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" }, 2071 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" }, 2072 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" }, 2073 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" }, 2074 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" }, 2075 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" }, 2076 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" }, 2077 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" }, 2078 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" }, 2079 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" }, 2080 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" }, 2081 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" }, 2082 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" }, 2083 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" }, 2084 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" }, 2085 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" }, 2086 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" }, 2087 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" }, 2088 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" }, 2089 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" }, 2090 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" }, 2091 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" }, 2092 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" }, 2093 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" }, 2094 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" }, 2095 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" }, 2096 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" }, 2097 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" }, 2098 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" }, 2099 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" }, 2100 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" }, 2101 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" }, 2102 /* switch stack: */ 2103 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" }, 2104 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" }, 2105 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" }, 2106 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" }, 2107 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" }, 2108 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" }, 2109 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" }, 2110 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" }, 2111 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" }, 2112 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" }, 2113 { PT_B0, "kb0" }, 2114 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" }, 2115 { PT_B4, "b4" }, { PT_B5, "b5" }, 2116 { PT_AR_PFS, "kar.pfs" }, 2117 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" }, 2118 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" }, 2119 { PT_PR, "k.pr" }, 2120 /* pt_regs */ 2121 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" }, 2122 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" }, 2123 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" }, 2124 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" }, 2125 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" }, 2126 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" }, 2127 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" }, 2128 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" }, 2129 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" }, 2130 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" }, 2131 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" }, 2132 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" }, 2133 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" }, 2134 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" }, 2135 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" }, 2136 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" }, 2137 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" }, 2138#else /* !IA64 */ 2139#ifdef I386 2140 { 4*EBX, "4*EBX" }, 2141 { 4*ECX, "4*ECX" }, 2142 { 4*EDX, "4*EDX" }, 2143 { 4*ESI, "4*ESI" }, 2144 { 4*EDI, "4*EDI" }, 2145 { 4*EBP, "4*EBP" }, 2146 { 4*EAX, "4*EAX" }, 2147 { 4*DS, "4*DS" }, 2148 { 4*ES, "4*ES" }, 2149 { 4*FS, "4*FS" }, 2150 { 4*GS, "4*GS" }, 2151 { 4*ORIG_EAX, "4*ORIG_EAX" }, 2152 { 4*EIP, "4*EIP" }, 2153 { 4*CS, "4*CS" }, 2154 { 4*EFL, "4*EFL" }, 2155 { 4*UESP, "4*UESP" }, 2156 { 4*SS, "4*SS" }, 2157#else /* !I386 */ 2158#ifdef X86_64 2159 { 8*RDI, "8*RDI" }, 2160 { 8*RSI, "8*RSI" }, 2161 { 8*RDX, "8*RDX" }, 2162 { 8*R10, "8*R10" }, 2163 { 8*R8, "8*R8" }, 2164 { 8*R9, "8*R9" }, 2165 { 8*RBX, "8*RBX" }, 2166 { 8*RCX, "8*RCX" }, 2167 { 8*RBP, "8*RBP" }, 2168 { 8*RAX, "8*RAX" }, 2169#if 0 2170 { 8*DS, "8*DS" }, 2171 { 8*ES, "8*ES" }, 2172 { 8*FS, "8*FS" }, 2173 { 8*GS, "8*GS" }, 2174#endif 2175 { 8*ORIG_RAX, "8*ORIG_EAX" }, 2176 { 8*RIP, "8*RIP" }, 2177 { 8*CS, "8*CS" }, 2178 { 8*EFLAGS, "8*EFL" }, 2179 { 8*RSP, "8*RSP" }, 2180 { 8*SS, "8*SS" }, 2181 { 8*R11, "8*R11" }, 2182 { 8*R12, "8*R12" }, 2183 { 8*R13, "8*R13" }, 2184 { 8*R14, "8*R14" }, 2185 { 8*R15, "8*R15" }, 2186#endif 2187#ifdef M68K 2188 { 4*PT_D1, "4*PT_D1" }, 2189 { 4*PT_D2, "4*PT_D2" }, 2190 { 4*PT_D3, "4*PT_D3" }, 2191 { 4*PT_D4, "4*PT_D4" }, 2192 { 4*PT_D5, "4*PT_D5" }, 2193 { 4*PT_D6, "4*PT_D6" }, 2194 { 4*PT_D7, "4*PT_D7" }, 2195 { 4*PT_A0, "4*PT_A0" }, 2196 { 4*PT_A1, "4*PT_A1" }, 2197 { 4*PT_A2, "4*PT_A2" }, 2198 { 4*PT_A3, "4*PT_A3" }, 2199 { 4*PT_A4, "4*PT_A4" }, 2200 { 4*PT_A5, "4*PT_A5" }, 2201 { 4*PT_A6, "4*PT_A6" }, 2202 { 4*PT_D0, "4*PT_D0" }, 2203 { 4*PT_USP, "4*PT_USP" }, 2204 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" }, 2205 { 4*PT_SR, "4*PT_SR" }, 2206 { 4*PT_PC, "4*PT_PC" }, 2207#endif /* M68K */ 2208#endif /* !I386 */ 2209#ifdef SH 2210 { 4*REG_REG0, "4*REG_REG0" }, 2211 { 4*(REG_REG0+1), "4*REG_REG1" }, 2212 { 4*(REG_REG0+2), "4*REG_REG2" }, 2213 { 4*(REG_REG0+3), "4*REG_REG3" }, 2214 { 4*(REG_REG0+4), "4*REG_REG4" }, 2215 { 4*(REG_REG0+5), "4*REG_REG5" }, 2216 { 4*(REG_REG0+6), "4*REG_REG6" }, 2217 { 4*(REG_REG0+7), "4*REG_REG7" }, 2218 { 4*(REG_REG0+8), "4*REG_REG8" }, 2219 { 4*(REG_REG0+9), "4*REG_REG9" }, 2220 { 4*(REG_REG0+10), "4*REG_REG10" }, 2221 { 4*(REG_REG0+11), "4*REG_REG11" }, 2222 { 4*(REG_REG0+12), "4*REG_REG12" }, 2223 { 4*(REG_REG0+13), "4*REG_REG13" }, 2224 { 4*(REG_REG0+14), "4*REG_REG14" }, 2225 { 4*REG_REG15, "4*REG_REG15" }, 2226 { 4*REG_PC, "4*REG_PC" }, 2227 { 4*REG_PR, "4*REG_PR" }, 2228 { 4*REG_SR, "4*REG_SR" }, 2229 { 4*REG_GBR, "4*REG_GBR" }, 2230 { 4*REG_MACH, "4*REG_MACH" }, 2231 { 4*REG_MACL, "4*REG_MACL" }, 2232 { 4*REG_SYSCALL, "4*REG_SYSCALL" }, 2233 { 4*REG_FPUL, "4*REG_FPUL" }, 2234 { 4*REG_FPREG0, "4*REG_FPREG0" }, 2235 { 4*(REG_FPREG0+1), "4*REG_FPREG1" }, 2236 { 4*(REG_FPREG0+2), "4*REG_FPREG2" }, 2237 { 4*(REG_FPREG0+3), "4*REG_FPREG3" }, 2238 { 4*(REG_FPREG0+4), "4*REG_FPREG4" }, 2239 { 4*(REG_FPREG0+5), "4*REG_FPREG5" }, 2240 { 4*(REG_FPREG0+6), "4*REG_FPREG6" }, 2241 { 4*(REG_FPREG0+7), "4*REG_FPREG7" }, 2242 { 4*(REG_FPREG0+8), "4*REG_FPREG8" }, 2243 { 4*(REG_FPREG0+9), "4*REG_FPREG9" }, 2244 { 4*(REG_FPREG0+10), "4*REG_FPREG10" }, 2245 { 4*(REG_FPREG0+11), "4*REG_FPREG11" }, 2246 { 4*(REG_FPREG0+12), "4*REG_FPREG12" }, 2247 { 4*(REG_FPREG0+13), "4*REG_FPREG13" }, 2248 { 4*(REG_FPREG0+14), "4*REG_FPREG14" }, 2249 { 4*REG_FPREG15, "4*REG_FPREG15" }, 2250 { 4*REG_XDREG0, "4*REG_XDREG0" }, 2251 { 4*(REG_XDREG0+2), "4*REG_XDREG2" }, 2252 { 4*(REG_XDREG0+4), "4*REG_XDREG4" }, 2253 { 4*(REG_XDREG0+6), "4*REG_XDREG6" }, 2254 { 4*(REG_XDREG0+8), "4*REG_XDREG8" }, 2255 { 4*(REG_XDREG0+10), "4*REG_XDREG10" }, 2256 { 4*(REG_XDREG0+12), "4*REG_XDREG12" }, 2257 { 4*REG_XDREG14, "4*REG_XDREG14" }, 2258 { 4*REG_FPSCR, "4*REG_FPSCR" }, 2259#endif /* SH */ 2260 2261#if !defined(S390) && !defined(S390X) && !defined(MIPS) 2262 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" }, 2263#endif 2264#if defined(I386) || defined(X86_64) 2265 { uoff(i387), "offsetof(struct user, i387)" }, 2266#else /* !I386 */ 2267#ifdef M68K 2268 { uoff(m68kfp), "offsetof(struct user, m68kfp)" }, 2269#endif /* M68K */ 2270#endif /* !I386 */ 2271 { uoff(u_tsize), "offsetof(struct user, u_tsize)" }, 2272 { uoff(u_dsize), "offsetof(struct user, u_dsize)" }, 2273 { uoff(u_ssize), "offsetof(struct user, u_ssize)" }, 2274 { uoff(start_code), "offsetof(struct user, start_code)" }, 2275 { uoff(start_stack), "offsetof(struct user, start_stack)" }, 2276 { uoff(signal), "offsetof(struct user, signal)" }, 2277#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) 2278 { uoff(reserved), "offsetof(struct user, reserved)" }, 2279#endif 2280 { uoff(u_ar0), "offsetof(struct user, u_ar0)" }, 2281#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) 2282 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" }, 2283#endif 2284 { uoff(magic), "offsetof(struct user, magic)" }, 2285 { uoff(u_comm), "offsetof(struct user, u_comm)" }, 2286#if defined(I386) || defined(X86_64) 2287 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" }, 2288#endif /* I386 */ 2289#endif /* !IA64 */ 2290#endif /* !ALPHA */ 2291#endif /* !POWERPC/!SPARC */ 2292#endif /* LINUX */ 2293#ifdef SUNOS4 2294 { uoff(u_pcb), "offsetof(struct user, u_pcb)" }, 2295 { uoff(u_procp), "offsetof(struct user, u_procp)" }, 2296 { uoff(u_ar0), "offsetof(struct user, u_ar0)" }, 2297 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" }, 2298 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" }, 2299 { uoff(u_ap), "offsetof(struct user, u_ap)" }, 2300 { uoff(u_qsave), "offsetof(struct user, u_qsave)" }, 2301 { uoff(u_rval1), "offsetof(struct user, u_rval1)" }, 2302 { uoff(u_rval2), "offsetof(struct user, u_rval2)" }, 2303 { uoff(u_error), "offsetof(struct user, u_error)" }, 2304 { uoff(u_eosys), "offsetof(struct user, u_eosys)" }, 2305 { uoff(u_ssave), "offsetof(struct user, u_ssave)" }, 2306 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" }, 2307 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" }, 2308 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" }, 2309 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" }, 2310 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" }, 2311 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" }, 2312 { uoff(u_code), "offsetof(struct user, u_code)" }, 2313 { uoff(u_addr), "offsetof(struct user, u_addr)" }, 2314 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" }, 2315 { uoff(u_ofile), "offsetof(struct user, u_ofile)" }, 2316 { uoff(u_pofile), "offsetof(struct user, u_pofile)" }, 2317 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" }, 2318 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"}, 2319 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" }, 2320 { uoff(u_cwd), "offsetof(struct user, u_cwd)" }, 2321 { uoff(u_cdir), "offsetof(struct user, u_cdir)" }, 2322 { uoff(u_rdir), "offsetof(struct user, u_rdir)" }, 2323 { uoff(u_cmask), "offsetof(struct user, u_cmask)" }, 2324 { uoff(u_ru), "offsetof(struct user, u_ru)" }, 2325 { uoff(u_cru), "offsetof(struct user, u_cru)" }, 2326 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" }, 2327 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" }, 2328 { uoff(u_ioch), "offsetof(struct user, u_ioch)" }, 2329 { uoff(u_start), "offsetof(struct user, u_start)" }, 2330 { uoff(u_acflag), "offsetof(struct user, u_acflag)" }, 2331 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" }, 2332 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" }, 2333 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" }, 2334 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"}, 2335 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" }, 2336 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" }, 2337 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"}, 2338 { uoff(u_lofault), "offsetof(struct user, u_lofault)" }, 2339#endif /* SUNOS4 */ 2340#ifndef HPPA 2341 { sizeof(struct user), "sizeof(struct user)" }, 2342#endif 2343 { 0, NULL }, 2344}; 2345#endif 2346 2347int 2348sys_ptrace(tcp) 2349struct tcb *tcp; 2350{ 2351 char *cmd; 2352 struct xlat *x; 2353 long addr; 2354 2355 cmd = xlookup(ptrace_cmds, tcp->u_arg[0]); 2356 if (!cmd) 2357#ifndef FREEBSD 2358 cmd = "PTRACE_???"; 2359#else 2360 cmd = "PT_???"; 2361#endif 2362 if (entering(tcp)) { 2363 tprintf("%s, %lu, ", cmd, tcp->u_arg[1]); 2364 addr = tcp->u_arg[2]; 2365#ifndef FREEBSD 2366 if (tcp->u_arg[0] == PTRACE_PEEKUSER 2367 || tcp->u_arg[0] == PTRACE_POKEUSER) { 2368 for (x = struct_user_offsets; x->str; x++) { 2369 if (x->val >= addr) 2370 break; 2371 } 2372 if (!x->str) 2373 tprintf("%#lx, ", addr); 2374 else if (x->val > addr && x != struct_user_offsets) { 2375 x--; 2376 tprintf("%s + %ld, ", x->str, addr - x->val); 2377 } 2378 else 2379 tprintf("%s, ", x->str); 2380 } 2381 else 2382#endif 2383 tprintf("%#lx, ", tcp->u_arg[2]); 2384#ifdef LINUX 2385 switch (tcp->u_arg[0]) { 2386 case PTRACE_PEEKDATA: 2387 case PTRACE_PEEKTEXT: 2388 case PTRACE_PEEKUSER: 2389 break; 2390 case PTRACE_CONT: 2391 case PTRACE_SINGLESTEP: 2392 case PTRACE_SYSCALL: 2393 case PTRACE_DETACH: 2394 printsignal(tcp->u_arg[3]); 2395 break; 2396 default: 2397 tprintf("%#lx", tcp->u_arg[3]); 2398 break; 2399 } 2400 } else { 2401 switch (tcp->u_arg[0]) { 2402 case PTRACE_PEEKDATA: 2403 case PTRACE_PEEKTEXT: 2404 case PTRACE_PEEKUSER: 2405 printnum(tcp, tcp->u_arg[3], "%#x"); 2406 break; 2407 } 2408 } 2409#endif /* LINUX */ 2410#ifdef SUNOS4 2411 if (tcp->u_arg[0] == PTRACE_WRITEDATA || 2412 tcp->u_arg[0] == PTRACE_WRITETEXT) { 2413 tprintf("%lu, ", tcp->u_arg[3]); 2414 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]); 2415 } else if (tcp->u_arg[0] != PTRACE_READDATA && 2416 tcp->u_arg[0] != PTRACE_READTEXT) { 2417 tprintf("%#lx", tcp->u_arg[3]); 2418 } 2419 } else { 2420 if (tcp->u_arg[0] == PTRACE_READDATA || 2421 tcp->u_arg[0] == PTRACE_READTEXT) { 2422 tprintf("%lu, ", tcp->u_arg[3]); 2423 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]); 2424 } 2425 } 2426#endif /* SUNOS4 */ 2427#ifdef FREEBSD 2428 tprintf("%lu", tcp->u_arg[3]); 2429 } 2430#endif /* FREEBSD */ 2431 return 0; 2432} 2433 2434#endif /* !SVR4 */ 2435 2436#ifdef LINUX 2437static struct xlat futexops[] = { 2438 { FUTEX_WAIT, "FUTEX_WAIT" }, 2439 { FUTEX_WAKE, "FUTEX_WAKE" }, 2440 { FUTEX_FD, "FUTEX_FD" }, 2441 { 0, NULL } 2442}; 2443 2444int 2445sys_futex(tcp) 2446struct tcb *tcp; 2447{ 2448 if (entering(tcp)) { 2449 tprintf("%p, ", (void *) tcp->u_arg[0]); 2450 printflags(futexops, tcp->u_arg[1]); 2451 tprintf(", %ld, ", tcp->u_arg[2]); 2452 printtv(tcp, tcp->u_arg[3]); 2453 } 2454 return 0; 2455} 2456 2457static void 2458print_affinitylist(list, len) 2459unsigned long *list; 2460unsigned int len; 2461{ 2462 int first = 1; 2463 tprintf(" {"); 2464 while (len > sizeof (unsigned long)) { 2465 tprintf("%s %lx", first ? "" : ",", *list++); 2466 first = 0; 2467 len -= sizeof (unsigned long); 2468 } 2469 tprintf(" }"); 2470} 2471 2472int 2473sys_sched_setaffinity(tcp) 2474struct tcb *tcp; 2475{ 2476 if (entering(tcp)) { 2477 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); 2478 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]); 2479 } 2480 return 0; 2481} 2482 2483int 2484sys_sched_getaffinity(tcp) 2485struct tcb *tcp; 2486{ 2487 if (entering(tcp)) { 2488 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); 2489 } else { 2490 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval); 2491 } 2492 return 0; 2493} 2494#endif 2495