1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl> 6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Linux for s390 port by D.J. Barrow 8 * <barrow_dj (at) mail.yahoo.com,djbarrow (at) de.ibm.com> 9 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH 10 * port by Greg Banks <gbanks (at) 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: process.c,v 1.97 2005/06/08 20:45:28 roland Exp $ 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 #ifdef HAVE_ANDROID_OS 49 #include <asm/user.h> 50 #else 51 #include <sys/user.h> 52 #endif 53 #include <sys/syscall.h> 54 #include <signal.h> 55 #ifdef SUNOS4 56 #include <machine/reg.h> 57 #endif /* SUNOS4 */ 58 59 #ifdef FREEBSD 60 #include <sys/ptrace.h> 61 #endif 62 63 #ifdef HAVE_ANDROID_OS 64 /* for struct sched_param */ 65 #define sched_priority __sched_priority 66 #endif 67 68 #if HAVE_ASM_REG_H 69 #if defined (SPARC) || defined (SPARC64) 70 # define fpq kernel_fpq 71 # define fq kernel_fq 72 # define fpu kernel_fpu 73 #endif /* SPARC || SPARC64 */ 74 #include <asm/reg.h> 75 #if defined (SPARC) || defined (SPARC64) 76 # undef fpq 77 # undef fq 78 # undef fpu 79 #endif /* SPARC || SPARC64 */ 80 #endif /* HAVE_ASM_REG_H */ 81 82 #ifdef HAVE_SYS_REG_H 83 # include <sys/reg.h> 84 #ifndef PTRACE_PEEKUSR 85 # define PTRACE_PEEKUSR PTRACE_PEEKUSER 86 #endif 87 #ifndef PTRACE_POKEUSR 88 # define PTRACE_POKEUSR PTRACE_POKEUSER 89 #endif 90 #endif 91 92 #ifdef HAVE_LINUX_PTRACE_H 93 #undef PTRACE_SYSCALL 94 # ifdef HAVE_STRUCT_IA64_FPREG 95 # define ia64_fpreg XXX_ia64_fpreg 96 # endif 97 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS 98 # define pt_all_user_regs XXX_pt_all_user_regs 99 # endif 100 #include <linux/ptrace.h> 101 # undef ia64_fpreg 102 # undef pt_all_user_regs 103 #endif 104 105 #if defined (LINUX) && defined (SPARC64) 106 # define r_pc r_tpc 107 # undef PTRACE_GETREGS 108 # define PTRACE_GETREGS PTRACE_GETREGS64 109 # undef PTRACE_SETREGS 110 # define PTRACE_SETREGS PTRACE_SETREGS64 111 #endif /* LINUX && SPARC64 */ 112 113 #ifdef HAVE_LINUX_FUTEX_H 114 #include <linux/futex.h> 115 #endif 116 #if defined LINUX 117 # ifndef FUTEX_WAIT 118 # define FUTEX_WAIT 0 119 # endif 120 # ifndef FUTEX_WAKE 121 # define FUTEX_WAKE 1 122 # endif 123 # ifndef FUTEX_FD 124 # define FUTEX_FD 2 125 # endif 126 # ifndef FUTEX_REQUEUE 127 # define FUTEX_REQUEUE 3 128 # endif 129 #endif 130 131 #ifdef LINUX 132 #include <sched.h> 133 #include <asm/posix_types.h> 134 #undef GETGROUPS_T 135 #define GETGROUPS_T __kernel_gid_t 136 #undef GETGROUPS32_T 137 #define GETGROUPS32_T __kernel_gid32_t 138 #endif /* LINUX */ 139 140 #if defined(LINUX) && defined(IA64) 141 # include <asm/ptrace_offsets.h> 142 # include <asm/rse.h> 143 #endif 144 145 #ifdef HAVE_PRCTL 146 #include <sys/prctl.h> 147 #endif 148 149 #ifndef WCOREDUMP 150 #define WCOREDUMP(status) ((status) & 0200) 151 #endif 152 153 /* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */ 154 #if defined(HAVE_PRCTL) 155 static const struct xlat prctl_options[] = { 156 #ifdef PR_MAXPROCS 157 { PR_MAXPROCS, "PR_MAXPROCS" }, 158 #endif 159 #ifdef PR_ISBLOCKED 160 { PR_ISBLOCKED, "PR_ISBLOCKED" }, 161 #endif 162 #ifdef PR_SETSTACKSIZE 163 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" }, 164 #endif 165 #ifdef PR_GETSTACKSIZE 166 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" }, 167 #endif 168 #ifdef PR_MAXPPROCS 169 { PR_MAXPPROCS, "PR_MAXPPROCS" }, 170 #endif 171 #ifdef PR_UNBLKONEXEC 172 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" }, 173 #endif 174 #ifdef PR_ATOMICSIM 175 { PR_ATOMICSIM, "PR_ATOMICSIM" }, 176 #endif 177 #ifdef PR_SETEXITSIG 178 { PR_SETEXITSIG, "PR_SETEXITSIG" }, 179 #endif 180 #ifdef PR_RESIDENT 181 { PR_RESIDENT, "PR_RESIDENT" }, 182 #endif 183 #ifdef PR_ATTACHADDR 184 { PR_ATTACHADDR, "PR_ATTACHADDR" }, 185 #endif 186 #ifdef PR_DETACHADDR 187 { PR_DETACHADDR, "PR_DETACHADDR" }, 188 #endif 189 #ifdef PR_TERMCHILD 190 { PR_TERMCHILD, "PR_TERMCHILD" }, 191 #endif 192 #ifdef PR_GETSHMASK 193 { PR_GETSHMASK, "PR_GETSHMASK" }, 194 #endif 195 #ifdef PR_GETNSHARE 196 { PR_GETNSHARE, "PR_GETNSHARE" }, 197 #endif 198 #if defined(PR_SET_PDEATHSIG) 199 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" }, 200 #endif 201 #ifdef PR_COREPID 202 { PR_COREPID, "PR_COREPID" }, 203 #endif 204 #ifdef PR_ATTACHADDRPERM 205 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" }, 206 #endif 207 #ifdef PR_PTHREADEXIT 208 { PR_PTHREADEXIT, "PR_PTHREADEXIT" }, 209 #endif 210 #ifdef PR_SET_PDEATHSIG 211 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" }, 212 #endif 213 #ifdef PR_GET_PDEATHSIG 214 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" }, 215 #endif 216 #ifdef PR_GET_UNALIGN 217 { PR_GET_UNALIGN, "PR_GET_UNALIGN" }, 218 #endif 219 #ifdef PR_SET_UNALIGN 220 { PR_SET_UNALIGN, "PR_SET_UNALIGN" }, 221 #endif 222 #ifdef PR_GET_KEEPCAPS 223 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" }, 224 #endif 225 #ifdef PR_SET_KEEPCAPS 226 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" }, 227 #endif 228 { 0, NULL }, 229 }; 230 231 232 static const char * 233 unalignctl_string (unsigned int ctl) 234 { 235 static char buf[16]; 236 237 switch (ctl) { 238 #ifdef PR_UNALIGN_NOPRINT 239 case PR_UNALIGN_NOPRINT: 240 return "NOPRINT"; 241 #endif 242 #ifdef PR_UNALIGN_SIGBUS 243 case PR_UNALIGN_SIGBUS: 244 return "SIGBUS"; 245 #endif 246 default: 247 break; 248 } 249 sprintf(buf, "%x", ctl); 250 return buf; 251 } 252 253 254 int 255 sys_prctl(tcp) 256 struct tcb *tcp; 257 { 258 int i; 259 260 if (entering(tcp)) { 261 printxval(prctl_options, tcp->u_arg[0], "PR_???"); 262 switch (tcp->u_arg[0]) { 263 #ifdef PR_GETNSHARE 264 case PR_GETNSHARE: 265 break; 266 #endif 267 #ifdef PR_SET_DEATHSIG 268 case PR_GET_PDEATHSIG: 269 break; 270 #endif 271 #ifdef PR_SET_UNALIGN 272 case PR_SET_UNALIGN: 273 tprintf(", %s", unalignctl_string(tcp->u_arg[1])); 274 break; 275 #endif 276 #ifdef PR_GET_UNALIGN 277 case PR_GET_UNALIGN: 278 tprintf(", %#lx", tcp->u_arg[1]); 279 break; 280 #endif 281 default: 282 for (i = 1; i < tcp->u_nargs; i++) 283 tprintf(", %#lx", tcp->u_arg[i]); 284 break; 285 } 286 } else { 287 switch (tcp->u_arg[0]) { 288 #ifdef PR_GET_PDEATHSIG 289 case PR_GET_PDEATHSIG: 290 for (i=1; i<tcp->u_nargs; i++) 291 tprintf(", %#lx", tcp->u_arg[i]); 292 break; 293 #endif 294 #ifdef PR_SET_UNALIGN 295 case PR_SET_UNALIGN: 296 break; 297 #endif 298 #ifdef PR_GET_UNALIGN 299 case PR_GET_UNALIGN: 300 { 301 int ctl; 302 303 umove(tcp, tcp->u_arg[1], &ctl); 304 tcp->auxstr = unalignctl_string(ctl); 305 return RVAL_STR; 306 } 307 #endif 308 default: 309 break; 310 } 311 } 312 return 0; 313 } 314 315 #endif /* HAVE_PRCTL */ 316 317 int 318 sys_gethostid(tcp) 319 struct tcb *tcp; 320 { 321 if (exiting(tcp)) 322 return RVAL_HEX; 323 return 0; 324 } 325 326 int 327 sys_sethostname(tcp) 328 struct tcb *tcp; 329 { 330 if (entering(tcp)) { 331 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]); 332 tprintf(", %lu", tcp->u_arg[1]); 333 } 334 return 0; 335 } 336 337 int 338 sys_gethostname(tcp) 339 struct tcb *tcp; 340 { 341 if (exiting(tcp)) { 342 if (syserror(tcp)) 343 tprintf("%#lx", tcp->u_arg[0]); 344 else 345 printpath(tcp, tcp->u_arg[0]); 346 tprintf(", %lu", tcp->u_arg[1]); 347 } 348 return 0; 349 } 350 351 int 352 sys_setdomainname(tcp) 353 struct tcb *tcp; 354 { 355 if (entering(tcp)) { 356 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]); 357 tprintf(", %lu", tcp->u_arg[1]); 358 } 359 return 0; 360 } 361 362 #if !defined(LINUX) 363 364 int 365 sys_getdomainname(tcp) 366 struct tcb *tcp; 367 { 368 if (exiting(tcp)) { 369 if (syserror(tcp)) 370 tprintf("%#lx", tcp->u_arg[0]); 371 else 372 printpath(tcp, tcp->u_arg[0]); 373 tprintf(", %lu", tcp->u_arg[1]); 374 } 375 return 0; 376 } 377 #endif /* !LINUX */ 378 379 int 380 sys_exit(tcp) 381 struct tcb *tcp; 382 { 383 if (exiting(tcp)) { 384 fprintf(stderr, "_exit returned!\n"); 385 return -1; 386 } 387 /* special case: we stop tracing this process, finish line now */ 388 tprintf("%ld) ", tcp->u_arg[0]); 389 tabto(acolumn); 390 tprintf("= ?"); 391 printtrailer(tcp); 392 return 0; 393 } 394 395 int 396 internal_exit(tcp) 397 struct tcb *tcp; 398 { 399 if (entering(tcp)) { 400 tcp->flags |= TCB_EXITING; 401 #ifdef __NR_exit_group 402 # ifdef IA64 403 if (ia32) { 404 if (tcp->scno == 252) 405 tcp->flags |= TCB_GROUP_EXITING; 406 } else 407 # endif 408 if (known_scno(tcp) == __NR_exit_group) 409 tcp->flags |= TCB_GROUP_EXITING; 410 #endif 411 } 412 return 0; 413 } 414 415 /* TCP is creating a child we want to follow. 416 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0. 417 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */ 418 static int 419 fork_tcb(struct tcb *tcp) 420 { 421 if (nprocs == tcbtabsize) { 422 if (expand_tcbtab()) { 423 tcp->flags &= ~TCB_FOLLOWFORK; 424 fprintf(stderr, "sys_fork: tcb table full\n"); 425 } 426 } 427 428 tcp->flags |= TCB_FOLLOWFORK; 429 return 0; 430 } 431 432 #ifdef USE_PROCFS 433 434 int 435 sys_fork(tcp) 436 struct tcb *tcp; 437 { 438 if (exiting(tcp)) { 439 if (getrval2(tcp)) { 440 tcp->auxstr = "child process"; 441 return RVAL_UDECIMAL | RVAL_STR; 442 } 443 } 444 return 0; 445 } 446 447 #if UNIXWARE > 2 448 449 int 450 sys_rfork(tcp) 451 struct tcb *tcp; 452 { 453 if (entering(tcp)) { 454 tprintf ("%ld", tcp->u_arg[0]); 455 } 456 else { 457 if (getrval2(tcp)) { 458 tcp->auxstr = "child process"; 459 return RVAL_UDECIMAL | RVAL_STR; 460 } 461 } 462 return 0; 463 } 464 465 #endif 466 467 int 468 internal_fork(tcp) 469 struct tcb *tcp; 470 { 471 struct tcb *tcpchild; 472 473 if (exiting(tcp)) { 474 #ifdef SYS_rfork 475 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC)) 476 return 0; 477 #endif 478 if (getrval2(tcp)) 479 return 0; 480 if (!followfork) 481 return 0; 482 if (fork_tcb(tcp)) 483 return 0; 484 if (syserror(tcp)) 485 return 0; 486 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) { 487 fprintf(stderr, "sys_fork: tcb table full\n"); 488 return 0; 489 } 490 if (proc_open(tcpchild, 2) < 0) 491 droptcb(tcpchild); 492 } 493 return 0; 494 } 495 496 #else /* !USE_PROCFS */ 497 498 #ifdef LINUX 499 500 /* defines copied from linux/sched.h since we can't include that 501 * ourselves (it conflicts with *lots* of libc includes) 502 */ 503 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ 504 #define CLONE_VM 0x00000100 /* set if VM shared between processes */ 505 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */ 506 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */ 507 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */ 508 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */ 509 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */ 510 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */ 511 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */ 512 #define CLONE_THREAD 0x00010000 /* Same thread group? */ 513 #define CLONE_NEWNS 0x00020000 /* New namespace group? */ 514 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */ 515 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ 516 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */ 517 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */ 518 #define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */ 519 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */ 520 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ 521 522 static const struct xlat clone_flags[] = { 523 { CLONE_VM, "CLONE_VM" }, 524 { CLONE_FS, "CLONE_FS" }, 525 { CLONE_FILES, "CLONE_FILES" }, 526 { CLONE_SIGHAND, "CLONE_SIGHAND" }, 527 { CLONE_IDLETASK, "CLONE_IDLETASK"}, 528 { CLONE_PTRACE, "CLONE_PTRACE" }, 529 { CLONE_VFORK, "CLONE_VFORK" }, 530 { CLONE_PARENT, "CLONE_PARENT" }, 531 { CLONE_THREAD, "CLONE_THREAD" }, 532 { CLONE_NEWNS, "CLONE_NEWNS" }, 533 { CLONE_SYSVSEM, "CLONE_SYSVSEM" }, 534 { CLONE_SETTLS, "CLONE_SETTLS" }, 535 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" }, 536 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" }, 537 { CLONE_DETACHED, "CLONE_DETACHED" }, 538 { CLONE_UNTRACED, "CLONE_UNTRACED" }, 539 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" }, 540 { 0, NULL }, 541 }; 542 543 # ifdef I386 544 # include <asm/ldt.h> 545 # ifdef HAVE_STRUCT_USER_DESC 546 # define modify_ldt_ldt_s user_desc 547 # endif 548 extern void print_ldt_entry(); 549 # endif 550 551 # if defined IA64 552 # define ARG_FLAGS 0 553 # define ARG_STACK 1 554 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1) 555 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2) 556 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3) 557 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4) 558 # elif defined S390 || defined S390X 559 # define ARG_STACK 0 560 # define ARG_FLAGS 1 561 # define ARG_PTID 2 562 # define ARG_CTID 3 563 # define ARG_TLS 4 564 # elif defined X86_64 || defined ALPHA 565 # define ARG_FLAGS 0 566 # define ARG_STACK 1 567 # define ARG_PTID 2 568 # define ARG_CTID 3 569 # define ARG_TLS 4 570 # else 571 # define ARG_FLAGS 0 572 # define ARG_STACK 1 573 # define ARG_PTID 2 574 # define ARG_TLS 3 575 # define ARG_CTID 4 576 # endif 577 578 int 579 sys_clone(tcp) 580 struct tcb *tcp; 581 { 582 if (exiting(tcp)) { 583 unsigned long flags = tcp->u_arg[ARG_FLAGS]; 584 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]); 585 # ifdef ARG_STACKSIZE 586 if (ARG_STACKSIZE != -1) 587 tprintf("stack_size=%#lx, ", 588 tcp->u_arg[ARG_STACKSIZE]); 589 # endif 590 tprintf("flags="); 591 printflags(clone_flags, flags &~ CSIGNAL, NULL); 592 if ((flags & CSIGNAL) != 0) 593 tprintf("|%s", signame(flags & CSIGNAL)); 594 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID 595 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0) 596 return 0; 597 if (flags & CLONE_PARENT_SETTID) 598 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]); 599 if (flags & CLONE_SETTLS) { 600 # ifdef I386 601 struct modify_ldt_ldt_s copy; 602 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) { 603 tprintf(", {entry_number:%d, ", 604 copy.entry_number); 605 if (!verbose(tcp)) 606 tprintf("...}"); 607 else 608 print_ldt_entry(©); 609 } 610 else 611 # endif 612 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]); 613 } 614 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID)) 615 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]); 616 } 617 return 0; 618 } 619 #endif 620 621 int 622 sys_fork(tcp) 623 struct tcb *tcp; 624 { 625 if (exiting(tcp)) 626 return RVAL_UDECIMAL; 627 return 0; 628 } 629 630 int 631 change_syscall(tcp, new) 632 struct tcb *tcp; 633 int new; 634 { 635 #if defined(LINUX) 636 #if defined(I386) 637 /* Attempt to make vfork into fork, which we can follow. */ 638 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0) 639 return -1; 640 return 0; 641 #elif defined(X86_64) 642 /* Attempt to make vfork into fork, which we can follow. */ 643 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0) 644 return -1; 645 return 0; 646 #elif defined(POWERPC) 647 if (ptrace(PTRACE_POKEUSER, tcp->pid, 648 (char*)(sizeof(unsigned long)*PT_R0), new) < 0) 649 return -1; 650 return 0; 651 #elif defined(S390) || defined(S390X) 652 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */ 653 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0) 654 return -1; 655 return 0; 656 #elif defined(M68K) 657 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0) 658 return -1; 659 return 0; 660 #elif defined(SPARC) || defined(SPARC64) 661 struct regs regs; 662 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0) 663 return -1; 664 regs.r_g1=new; 665 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0) 666 return -1; 667 return 0; 668 #elif defined(MIPS) 669 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0) 670 return -1; 671 return 0; 672 #elif defined(ALPHA) 673 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0) 674 return -1; 675 return 0; 676 #elif defined(IA64) 677 if (ia32) { 678 switch (new) { 679 case 2: break; /* x86 SYS_fork */ 680 case SYS_clone: new = 120; break; 681 default: 682 fprintf(stderr, "%s: unexpected syscall %d\n", 683 __FUNCTION__, new); 684 return -1; 685 } 686 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0) 687 return -1; 688 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0) 689 return -1; 690 return 0; 691 #elif defined(HPPA) 692 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0) 693 return -1; 694 return 0; 695 #elif defined(SH) 696 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0) 697 return -1; 698 return 0; 699 #elif defined(SH64) 700 /* Top half of reg encodes the no. of args n as 0x1n. 701 Assume 0 args as kernel never actually checks... */ 702 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), 703 0x100000 | new) < 0) 704 return -1; 705 return 0; 706 #elif defined(ARM) 707 /* Some kernels support this, some (pre-2.6.16 or so) don't. */ 708 # ifndef PTRACE_SET_SYSCALL 709 # define PTRACE_SET_SYSCALL 23 710 # endif 711 712 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0) 713 return -1; 714 715 return 0; 716 #else 717 #warning Do not know how to handle change_syscall for this architecture 718 #endif /* architecture */ 719 #endif /* LINUX */ 720 return -1; 721 } 722 723 #if 0 724 int 725 setarg(tcp, argnum) 726 struct tcb *tcp; 727 int argnum; 728 { 729 #if defined (IA64) 730 { 731 unsigned long *bsp, *ap; 732 733 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0) 734 return -1; 735 736 ap = ia64_rse_skip_regs(bsp, argnum); 737 errno = 0; 738 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]); 739 if (errno) 740 return -1; 741 742 } 743 #elif defined(I386) 744 { 745 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]); 746 if (errno) 747 return -1; 748 } 749 #elif defined(X86_64) 750 { 751 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]); 752 if (errno) 753 return -1; 754 } 755 #elif defined(POWERPC) 756 #ifndef PT_ORIG_R3 757 #define PT_ORIG_R3 34 758 #endif 759 { 760 ptrace(PTRACE_POKEUSER, tcp->pid, 761 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)), 762 tcp->u_arg[argnum]); 763 if (errno) 764 return -1; 765 } 766 #elif defined(MIPS) 767 { 768 errno = 0; 769 if (argnum < 4) 770 ptrace(PTRACE_POKEUSER, tcp->pid, 771 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]); 772 else { 773 unsigned long *sp; 774 775 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0) 776 return -1; 777 778 ptrace(PTRACE_POKEDATA, tcp->pid, 779 (char*)(sp + argnum - 4), tcp->u_arg[argnum]); 780 } 781 if (errno) 782 return -1; 783 } 784 #elif defined(S390) || defined(S390X) 785 { 786 if(argnum <= 5) 787 ptrace(PTRACE_POKEUSER, tcp->pid, 788 (char *) (argnum==0 ? PT_ORIGGPR2 : 789 PT_GPR2 + argnum*sizeof(long)), 790 tcp->u_arg[argnum]); 791 else 792 return -E2BIG; 793 if (errno) 794 return -1; 795 } 796 #else 797 # warning Sorry, setargs not implemented for this architecture. 798 #endif 799 return 0; 800 } 801 #endif 802 803 #if defined SYS_clone || defined SYS_clone2 || defined __NR_clone 804 int 805 internal_clone(tcp) 806 struct tcb *tcp; 807 { 808 struct tcb *tcpchild; 809 int pid; 810 if (entering(tcp)) { 811 if (!followfork) 812 return 0; 813 if (fork_tcb(tcp)) 814 return 0; 815 if (setbpt(tcp) < 0) 816 return 0; 817 } else { 818 int bpt = tcp->flags & TCB_BPTSET; 819 820 if (!(tcp->flags & TCB_FOLLOWFORK)) 821 return 0; 822 823 if (syserror(tcp)) { 824 if (bpt) 825 clearbpt(tcp); 826 return 0; 827 } 828 829 pid = tcp->u_rval; 830 831 #ifdef CLONE_PTRACE /* See new setbpt code. */ 832 tcpchild = pid2tcb(pid); 833 if (tcpchild != NULL) { 834 /* The child already reported its startup trap 835 before the parent reported its syscall return. */ 836 if ((tcpchild->flags 837 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED)) 838 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED)) 839 fprintf(stderr, "\ 840 [preattached child %d of %d in weird state!]\n", 841 pid, tcp->pid); 842 } 843 else 844 #endif 845 if ((tcpchild = alloctcb(pid)) == NULL) { 846 if (bpt) 847 clearbpt(tcp); 848 fprintf(stderr, " [tcb table full]\n"); 849 kill(pid, SIGKILL); /* XXX */ 850 return 0; 851 } 852 853 #ifndef CLONE_PTRACE 854 /* Attach to the new child */ 855 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) { 856 if (bpt) 857 clearbpt(tcp); 858 perror("PTRACE_ATTACH"); 859 fprintf(stderr, "Too late?\n"); 860 droptcb(tcpchild); 861 return 0; 862 } 863 #endif 864 865 if (bpt) 866 clearbpt(tcp); 867 868 tcpchild->flags |= TCB_ATTACHED; 869 /* Child has BPT too, must be removed on first occasion. */ 870 if (bpt) { 871 tcpchild->flags |= TCB_BPTSET; 872 tcpchild->baddr = tcp->baddr; 873 memcpy(tcpchild->inst, tcp->inst, 874 sizeof tcpchild->inst); 875 } 876 tcpchild->parent = tcp; 877 tcp->nchildren++; 878 if (tcpchild->flags & TCB_SUSPENDED) { 879 /* The child was born suspended, due to our having 880 forced CLONE_PTRACE. */ 881 if (bpt) 882 clearbpt(tcpchild); 883 884 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP); 885 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) { 886 perror("resume: ptrace(PTRACE_SYSCALL, ...)"); 887 return -1; 888 } 889 890 if (!qflag) 891 fprintf(stderr, "\ 892 Process %u resumed (parent %d ready)\n", 893 pid, tcp->pid); 894 } 895 else { 896 newoutf(tcpchild); 897 if (!qflag) 898 fprintf(stderr, "Process %d attached\n", pid); 899 } 900 901 #ifdef TCB_CLONE_THREAD 902 { 903 /* 904 * Save the flags used in this call, 905 * in case we point TCP to our parent below. 906 */ 907 int call_flags = tcp->u_arg[ARG_FLAGS]; 908 if ((tcp->flags & TCB_CLONE_THREAD) && 909 tcp->parent != NULL) { 910 /* The parent in this clone is itself a 911 thread belonging to another process. 912 There is no meaning to the parentage 913 relationship of the new child with the 914 thread, only with the process. We 915 associate the new thread with our 916 parent. Since this is done for every 917 new thread, there will never be a 918 TCB_CLONE_THREAD process that has 919 children. */ 920 --tcp->nchildren; 921 tcp = tcp->parent; 922 tcpchild->parent = tcp; 923 ++tcp->nchildren; 924 } 925 if (call_flags & CLONE_THREAD) { 926 tcpchild->flags |= TCB_CLONE_THREAD; 927 ++tcp->nclone_threads; 928 } 929 if (call_flags & CLONE_DETACHED) { 930 tcpchild->flags |= TCB_CLONE_DETACHED; 931 ++tcp->nclone_detached; 932 } 933 } 934 #endif 935 936 } 937 return 0; 938 } 939 #endif 940 941 int 942 internal_fork(tcp) 943 struct tcb *tcp; 944 { 945 #ifdef LINUX 946 /* We do special magic with clone for any clone or fork. */ 947 return internal_clone(tcp); 948 #else 949 950 struct tcb *tcpchild; 951 int pid; 952 int dont_follow = 0; 953 954 #ifdef SYS_vfork 955 if (known_scno(tcp) == SYS_vfork) { 956 /* Attempt to make vfork into fork, which we can follow. */ 957 if (!followvfork || 958 change_syscall(tcp, SYS_fork) < 0) 959 dont_follow = 1; 960 } 961 #endif 962 if (entering(tcp)) { 963 if (!followfork || dont_follow) 964 return 0; 965 if (fork_tcb(tcp)) 966 return 0; 967 if (setbpt(tcp) < 0) 968 return 0; 969 } 970 else { 971 int bpt = tcp->flags & TCB_BPTSET; 972 973 if (!(tcp->flags & TCB_FOLLOWFORK)) 974 return 0; 975 if (bpt) 976 clearbpt(tcp); 977 978 if (syserror(tcp)) 979 return 0; 980 981 pid = tcp->u_rval; 982 if ((tcpchild = alloctcb(pid)) == NULL) { 983 fprintf(stderr, " [tcb table full]\n"); 984 kill(pid, SIGKILL); /* XXX */ 985 return 0; 986 } 987 #ifdef LINUX 988 #ifdef HPPA 989 /* The child must have run before it can be attached. */ 990 /* This must be a bug in the parisc kernel, but I havn't 991 * identified it yet. Seems to be an issue associated 992 * with attaching to a process (which sends it a signal) 993 * before that process has ever been scheduled. When 994 * debugging, I started seeing crashes in 995 * arch/parisc/kernel/signal.c:do_signal(), apparently 996 * caused by r8 getting corrupt over the dequeue_signal() 997 * call. Didn't make much sense though... 998 */ 999 { 1000 struct timeval tv; 1001 tv.tv_sec = 0; 1002 tv.tv_usec = 10000; 1003 select(0, NULL, NULL, NULL, &tv); 1004 } 1005 #endif 1006 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) { 1007 perror("PTRACE_ATTACH"); 1008 fprintf(stderr, "Too late?\n"); 1009 droptcb(tcpchild); 1010 return 0; 1011 } 1012 #endif /* LINUX */ 1013 #ifdef SUNOS4 1014 #ifdef oldway 1015 /* The child must have run before it can be attached. */ 1016 { 1017 struct timeval tv; 1018 tv.tv_sec = 0; 1019 tv.tv_usec = 10000; 1020 select(0, NULL, NULL, NULL, &tv); 1021 } 1022 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) { 1023 perror("PTRACE_ATTACH"); 1024 fprintf(stderr, "Too late?\n"); 1025 droptcb(tcpchild); 1026 return 0; 1027 } 1028 #else /* !oldway */ 1029 /* Try to catch the new process as soon as possible. */ 1030 { 1031 int i; 1032 for (i = 0; i < 1024; i++) 1033 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0) 1034 break; 1035 if (i == 1024) { 1036 perror("PTRACE_ATTACH"); 1037 fprintf(stderr, "Too late?\n"); 1038 droptcb(tcpchild); 1039 return 0; 1040 } 1041 } 1042 #endif /* !oldway */ 1043 #endif /* SUNOS4 */ 1044 tcpchild->flags |= TCB_ATTACHED; 1045 /* Child has BPT too, must be removed on first occasion */ 1046 if (bpt) { 1047 tcpchild->flags |= TCB_BPTSET; 1048 tcpchild->baddr = tcp->baddr; 1049 memcpy(tcpchild->inst, tcp->inst, 1050 sizeof tcpchild->inst); 1051 } 1052 newoutf(tcpchild); 1053 tcpchild->parent = tcp; 1054 tcp->nchildren++; 1055 if (!qflag) 1056 fprintf(stderr, "Process %d attached\n", pid); 1057 } 1058 return 0; 1059 #endif 1060 } 1061 1062 #endif /* !USE_PROCFS */ 1063 1064 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD) 1065 1066 int 1067 sys_vfork(tcp) 1068 struct tcb *tcp; 1069 { 1070 if (exiting(tcp)) 1071 return RVAL_UDECIMAL; 1072 return 0; 1073 } 1074 1075 #endif /* SUNOS4 || LINUX || FREEBSD */ 1076 1077 #ifndef LINUX 1078 1079 static char idstr[16]; 1080 1081 int 1082 sys_getpid(tcp) 1083 struct tcb *tcp; 1084 { 1085 if (exiting(tcp)) { 1086 sprintf(idstr, "ppid %lu", getrval2(tcp)); 1087 tcp->auxstr = idstr; 1088 return RVAL_STR; 1089 } 1090 return 0; 1091 } 1092 1093 int 1094 sys_getuid(tcp) 1095 struct tcb *tcp; 1096 { 1097 if (exiting(tcp)) { 1098 sprintf(idstr, "euid %lu", getrval2(tcp)); 1099 tcp->auxstr = idstr; 1100 return RVAL_STR; 1101 } 1102 return 0; 1103 } 1104 1105 int 1106 sys_getgid(tcp) 1107 struct tcb *tcp; 1108 { 1109 if (exiting(tcp)) { 1110 sprintf(idstr, "egid %lu", getrval2(tcp)); 1111 tcp->auxstr = idstr; 1112 return RVAL_STR; 1113 } 1114 return 0; 1115 } 1116 1117 #endif /* !LINUX */ 1118 1119 #ifdef LINUX 1120 1121 int 1122 sys_setuid(tcp) 1123 struct tcb *tcp; 1124 { 1125 if (entering(tcp)) { 1126 tprintf("%u", (uid_t) tcp->u_arg[0]); 1127 } 1128 return 0; 1129 } 1130 1131 int 1132 sys_setgid(tcp) 1133 struct tcb *tcp; 1134 { 1135 if (entering(tcp)) { 1136 tprintf("%u", (gid_t) tcp->u_arg[0]); 1137 } 1138 return 0; 1139 } 1140 1141 int 1142 sys_getresuid(tcp) 1143 struct tcb *tcp; 1144 { 1145 if (exiting(tcp)) { 1146 __kernel_uid_t uid; 1147 if (syserror(tcp)) 1148 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0], 1149 tcp->u_arg[1], tcp->u_arg[2]); 1150 else { 1151 if (umove(tcp, tcp->u_arg[0], &uid) < 0) 1152 tprintf("%#lx, ", tcp->u_arg[0]); 1153 else 1154 tprintf("[%lu], ", (unsigned long) uid); 1155 if (umove(tcp, tcp->u_arg[1], &uid) < 0) 1156 tprintf("%#lx, ", tcp->u_arg[1]); 1157 else 1158 tprintf("[%lu], ", (unsigned long) uid); 1159 if (umove(tcp, tcp->u_arg[2], &uid) < 0) 1160 tprintf("%#lx", tcp->u_arg[2]); 1161 else 1162 tprintf("[%lu]", (unsigned long) uid); 1163 } 1164 } 1165 return 0; 1166 } 1167 1168 int 1169 sys_getresgid(tcp) 1170 struct tcb *tcp; 1171 { 1172 if (exiting(tcp)) { 1173 __kernel_gid_t gid; 1174 if (syserror(tcp)) 1175 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0], 1176 tcp->u_arg[1], tcp->u_arg[2]); 1177 else { 1178 if (umove(tcp, tcp->u_arg[0], &gid) < 0) 1179 tprintf("%#lx, ", tcp->u_arg[0]); 1180 else 1181 tprintf("[%lu], ", (unsigned long) gid); 1182 if (umove(tcp, tcp->u_arg[1], &gid) < 0) 1183 tprintf("%#lx, ", tcp->u_arg[1]); 1184 else 1185 tprintf("[%lu], ", (unsigned long) gid); 1186 if (umove(tcp, tcp->u_arg[2], &gid) < 0) 1187 tprintf("%#lx", tcp->u_arg[2]); 1188 else 1189 tprintf("[%lu]", (unsigned long) gid); 1190 } 1191 } 1192 return 0; 1193 } 1194 1195 #endif /* LINUX */ 1196 1197 int 1198 sys_setreuid(tcp) 1199 struct tcb *tcp; 1200 { 1201 if (entering(tcp)) { 1202 printuid("", tcp->u_arg[0]); 1203 printuid(", ", tcp->u_arg[1]); 1204 } 1205 return 0; 1206 } 1207 1208 int 1209 sys_setregid(tcp) 1210 struct tcb *tcp; 1211 { 1212 if (entering(tcp)) { 1213 printuid("", tcp->u_arg[0]); 1214 printuid(", ", tcp->u_arg[1]); 1215 } 1216 return 0; 1217 } 1218 1219 #if defined(LINUX) || defined(FREEBSD) 1220 int 1221 sys_setresuid(tcp) 1222 struct tcb *tcp; 1223 { 1224 if (entering(tcp)) { 1225 printuid("", tcp->u_arg[0]); 1226 printuid(", ", tcp->u_arg[1]); 1227 printuid(", ", tcp->u_arg[2]); 1228 } 1229 return 0; 1230 } 1231 int 1232 sys_setresgid(tcp) 1233 struct tcb *tcp; 1234 { 1235 if (entering(tcp)) { 1236 printuid("", tcp->u_arg[0]); 1237 printuid(", ", tcp->u_arg[1]); 1238 printuid(", ", tcp->u_arg[2]); 1239 } 1240 return 0; 1241 } 1242 1243 #endif /* LINUX || FREEBSD */ 1244 1245 int 1246 sys_setgroups(tcp) 1247 struct tcb *tcp; 1248 { 1249 if (entering(tcp)) { 1250 unsigned long len, size, start, cur, end, abbrev_end; 1251 GETGROUPS_T gid; 1252 int failed = 0; 1253 1254 len = tcp->u_arg[0]; 1255 tprintf("%lu, ", len); 1256 if (len == 0) { 1257 tprintf("[]"); 1258 return 0; 1259 } 1260 start = tcp->u_arg[1]; 1261 if (start == 0) { 1262 tprintf("NULL"); 1263 return 0; 1264 } 1265 size = len * sizeof(gid); 1266 end = start + size; 1267 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) { 1268 tprintf("%#lx", start); 1269 return 0; 1270 } 1271 if (abbrev(tcp)) { 1272 abbrev_end = start + max_strlen * sizeof(gid); 1273 if (abbrev_end < start) 1274 abbrev_end = end; 1275 } else { 1276 abbrev_end = end; 1277 } 1278 tprintf("["); 1279 for (cur = start; cur < end; cur += sizeof(gid)) { 1280 if (cur > start) 1281 tprintf(", "); 1282 if (cur >= abbrev_end) { 1283 tprintf("..."); 1284 break; 1285 } 1286 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) { 1287 tprintf("?"); 1288 failed = 1; 1289 break; 1290 } 1291 tprintf("%lu", (unsigned long) gid); 1292 } 1293 tprintf("]"); 1294 if (failed) 1295 tprintf(" %#lx", tcp->u_arg[1]); 1296 } 1297 return 0; 1298 } 1299 1300 int 1301 sys_getgroups(tcp) 1302 struct tcb *tcp; 1303 { 1304 unsigned long len; 1305 1306 if (entering(tcp)) { 1307 len = tcp->u_arg[0]; 1308 tprintf("%lu, ", len); 1309 } else { 1310 unsigned long size, start, cur, end, abbrev_end; 1311 GETGROUPS_T gid; 1312 int failed = 0; 1313 1314 len = tcp->u_rval; 1315 if (len == 0) { 1316 tprintf("[]"); 1317 return 0; 1318 } 1319 start = tcp->u_arg[1]; 1320 if (start == 0) { 1321 tprintf("NULL"); 1322 return 0; 1323 } 1324 if (tcp->u_arg[0] == 0) { 1325 tprintf("%#lx", start); 1326 return 0; 1327 } 1328 size = len * sizeof(gid); 1329 end = start + size; 1330 if (!verbose(tcp) || tcp->u_arg[0] == 0 || 1331 size / sizeof(gid) != len || end < start) { 1332 tprintf("%#lx", start); 1333 return 0; 1334 } 1335 if (abbrev(tcp)) { 1336 abbrev_end = start + max_strlen * sizeof(gid); 1337 if (abbrev_end < start) 1338 abbrev_end = end; 1339 } else { 1340 abbrev_end = end; 1341 } 1342 tprintf("["); 1343 for (cur = start; cur < end; cur += sizeof(gid)) { 1344 if (cur > start) 1345 tprintf(", "); 1346 if (cur >= abbrev_end) { 1347 tprintf("..."); 1348 break; 1349 } 1350 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) { 1351 tprintf("?"); 1352 failed = 1; 1353 break; 1354 } 1355 tprintf("%lu", (unsigned long) gid); 1356 } 1357 tprintf("]"); 1358 if (failed) 1359 tprintf(" %#lx", tcp->u_arg[1]); 1360 } 1361 return 0; 1362 } 1363 1364 #ifdef LINUX 1365 int 1366 sys_setgroups32(tcp) 1367 struct tcb *tcp; 1368 { 1369 if (entering(tcp)) { 1370 unsigned long len, size, start, cur, end, abbrev_end; 1371 GETGROUPS32_T gid; 1372 int failed = 0; 1373 1374 len = tcp->u_arg[0]; 1375 tprintf("%lu, ", len); 1376 if (len == 0) { 1377 tprintf("[]"); 1378 return 0; 1379 } 1380 start = tcp->u_arg[1]; 1381 if (start == 0) { 1382 tprintf("NULL"); 1383 return 0; 1384 } 1385 size = len * sizeof(gid); 1386 end = start + size; 1387 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) { 1388 tprintf("%#lx", start); 1389 return 0; 1390 } 1391 if (abbrev(tcp)) { 1392 abbrev_end = start + max_strlen * sizeof(gid); 1393 if (abbrev_end < start) 1394 abbrev_end = end; 1395 } else { 1396 abbrev_end = end; 1397 } 1398 tprintf("["); 1399 for (cur = start; cur < end; cur += sizeof(gid)) { 1400 if (cur > start) 1401 tprintf(", "); 1402 if (cur >= abbrev_end) { 1403 tprintf("..."); 1404 break; 1405 } 1406 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) { 1407 tprintf("?"); 1408 failed = 1; 1409 break; 1410 } 1411 tprintf("%lu", (unsigned long) gid); 1412 } 1413 tprintf("]"); 1414 if (failed) 1415 tprintf(" %#lx", tcp->u_arg[1]); 1416 } 1417 return 0; 1418 } 1419 1420 int 1421 sys_getgroups32(tcp) 1422 struct tcb *tcp; 1423 { 1424 unsigned long len; 1425 1426 if (entering(tcp)) { 1427 len = tcp->u_arg[0]; 1428 tprintf("%lu, ", len); 1429 } else { 1430 unsigned long size, start, cur, end, abbrev_end; 1431 GETGROUPS32_T gid; 1432 int failed = 0; 1433 1434 len = tcp->u_rval; 1435 if (len == 0) { 1436 tprintf("[]"); 1437 return 0; 1438 } 1439 start = tcp->u_arg[1]; 1440 if (start == 0) { 1441 tprintf("NULL"); 1442 return 0; 1443 } 1444 size = len * sizeof(gid); 1445 end = start + size; 1446 if (!verbose(tcp) || tcp->u_arg[0] == 0 || 1447 size / sizeof(gid) != len || end < start) { 1448 tprintf("%#lx", start); 1449 return 0; 1450 } 1451 if (abbrev(tcp)) { 1452 abbrev_end = start + max_strlen * sizeof(gid); 1453 if (abbrev_end < start) 1454 abbrev_end = end; 1455 } else { 1456 abbrev_end = end; 1457 } 1458 tprintf("["); 1459 for (cur = start; cur < end; cur += sizeof(gid)) { 1460 if (cur > start) 1461 tprintf(", "); 1462 if (cur >= abbrev_end) { 1463 tprintf("..."); 1464 break; 1465 } 1466 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) { 1467 tprintf("?"); 1468 failed = 1; 1469 break; 1470 } 1471 tprintf("%lu", (unsigned long) gid); 1472 } 1473 tprintf("]"); 1474 if (failed) 1475 tprintf(" %#lx", tcp->u_arg[1]); 1476 } 1477 return 0; 1478 } 1479 #endif /* LINUX */ 1480 1481 int 1482 sys_setpgrp(tcp) 1483 struct tcb *tcp; 1484 { 1485 if (entering(tcp)) { 1486 #ifndef SVR4 1487 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]); 1488 #endif /* !SVR4 */ 1489 } 1490 return 0; 1491 } 1492 1493 int 1494 sys_getpgrp(tcp) 1495 struct tcb *tcp; 1496 { 1497 if (entering(tcp)) { 1498 #ifndef SVR4 1499 tprintf("%lu", tcp->u_arg[0]); 1500 #endif /* !SVR4 */ 1501 } 1502 return 0; 1503 } 1504 1505 int 1506 sys_getsid(tcp) 1507 struct tcb *tcp; 1508 { 1509 if (entering(tcp)) { 1510 tprintf("%lu", tcp->u_arg[0]); 1511 } 1512 return 0; 1513 } 1514 1515 int 1516 sys_setsid(tcp) 1517 struct tcb *tcp; 1518 { 1519 return 0; 1520 } 1521 1522 int 1523 sys_getpgid(tcp) 1524 struct tcb *tcp; 1525 { 1526 if (entering(tcp)) { 1527 tprintf("%lu", tcp->u_arg[0]); 1528 } 1529 return 0; 1530 } 1531 1532 int 1533 sys_setpgid(tcp) 1534 struct tcb *tcp; 1535 { 1536 if (entering(tcp)) { 1537 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]); 1538 } 1539 return 0; 1540 } 1541 1542 #if UNIXWARE >= 2 1543 1544 #include <sys/privilege.h> 1545 1546 1547 static const struct xlat procpriv_cmds [] = { 1548 { SETPRV, "SETPRV" }, 1549 { CLRPRV, "CLRPRV" }, 1550 { PUTPRV, "PUTPRV" }, 1551 { GETPRV, "GETPRV" }, 1552 { CNTPRV, "CNTPRV" }, 1553 { 0, NULL }, 1554 }; 1555 1556 1557 static const struct xlat procpriv_priv [] = { 1558 { P_OWNER, "P_OWNER" }, 1559 { P_AUDIT, "P_AUDIT" }, 1560 { P_COMPAT, "P_COMPAT" }, 1561 { P_DACREAD, "P_DACREAD" }, 1562 { P_DACWRITE, "P_DACWRITE" }, 1563 { P_DEV, "P_DEV" }, 1564 { P_FILESYS, "P_FILESYS" }, 1565 { P_MACREAD, "P_MACREAD" }, 1566 { P_MACWRITE, "P_MACWRITE" }, 1567 { P_MOUNT, "P_MOUNT" }, 1568 { P_MULTIDIR, "P_MULTIDIR" }, 1569 { P_SETPLEVEL, "P_SETPLEVEL" }, 1570 { P_SETSPRIV, "P_SETSPRIV" }, 1571 { P_SETUID, "P_SETUID" }, 1572 { P_SYSOPS, "P_SYSOPS" }, 1573 { P_SETUPRIV, "P_SETUPRIV" }, 1574 { P_DRIVER, "P_DRIVER" }, 1575 { P_RTIME, "P_RTIME" }, 1576 { P_MACUPGRADE, "P_MACUPGRADE" }, 1577 { P_FSYSRANGE, "P_FSYSRANGE" }, 1578 { P_SETFLEVEL, "P_SETFLEVEL" }, 1579 { P_AUDITWR, "P_AUDITWR" }, 1580 { P_TSHAR, "P_TSHAR" }, 1581 { P_PLOCK, "P_PLOCK" }, 1582 { P_CORE, "P_CORE" }, 1583 { P_LOADMOD, "P_LOADMOD" }, 1584 { P_BIND, "P_BIND" }, 1585 { P_ALLPRIVS, "P_ALLPRIVS" }, 1586 { 0, NULL }, 1587 }; 1588 1589 1590 static const struct xlat procpriv_type [] = { 1591 { PS_FIX, "PS_FIX" }, 1592 { PS_INH, "PS_INH" }, 1593 { PS_MAX, "PS_MAX" }, 1594 { PS_WKG, "PS_WKG" }, 1595 { 0, NULL }, 1596 }; 1597 1598 1599 static void 1600 printpriv(tcp, addr, len, opt) 1601 struct tcb *tcp; 1602 long addr; 1603 int len; 1604 const struct xlat *opt; 1605 { 1606 priv_t buf [128]; 1607 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10; 1608 int dots = len > max; 1609 int i; 1610 1611 if (len > max) len = max; 1612 1613 if (len <= 0 || 1614 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0) 1615 { 1616 tprintf ("%#lx", addr); 1617 return; 1618 } 1619 1620 tprintf ("["); 1621 1622 for (i = 0; i < len; ++i) { 1623 char *t, *p; 1624 1625 if (i) tprintf (", "); 1626 1627 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) && 1628 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE))) 1629 { 1630 tprintf ("%s|%s", t, p); 1631 } 1632 else { 1633 tprintf ("%#lx", buf [i]); 1634 } 1635 } 1636 1637 if (dots) tprintf (" ..."); 1638 1639 tprintf ("]"); 1640 } 1641 1642 1643 int 1644 sys_procpriv(tcp) 1645 struct tcb *tcp; 1646 { 1647 if (entering(tcp)) { 1648 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV"); 1649 switch (tcp->u_arg[0]) { 1650 case CNTPRV: 1651 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]); 1652 break; 1653 1654 case GETPRV: 1655 break; 1656 1657 default: 1658 tprintf (", "); 1659 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]); 1660 tprintf (", %ld", tcp->u_arg[2]); 1661 } 1662 } 1663 else if (tcp->u_arg[0] == GETPRV) { 1664 if (syserror (tcp)) { 1665 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]); 1666 } 1667 else { 1668 tprintf (", "); 1669 printpriv (tcp, tcp->u_arg[1], tcp->u_rval); 1670 tprintf (", %ld", tcp->u_arg[2]); 1671 } 1672 } 1673 1674 return 0; 1675 } 1676 1677 #endif 1678 1679 1680 static void 1681 printargv(tcp, addr) 1682 struct tcb *tcp; 1683 long addr; 1684 { 1685 char *cp; 1686 char *sep; 1687 int max = max_strlen / 2; 1688 1689 for (sep = ""; --max >= 0; sep = ", ") { 1690 if (!abbrev(tcp)) 1691 max++; 1692 if (umove(tcp, addr, &cp) < 0) { 1693 tprintf("%#lx", addr); 1694 return; 1695 } 1696 if (cp == 0) 1697 break; 1698 tprintf("%s", sep); 1699 printstr(tcp, (long) cp, -1); 1700 addr += sizeof(char *); 1701 } 1702 if (cp) 1703 tprintf(", ..."); 1704 } 1705 1706 static void 1707 printargc(fmt, tcp, addr) 1708 char *fmt; 1709 struct tcb *tcp; 1710 long addr; 1711 { 1712 int count; 1713 char *cp; 1714 1715 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) { 1716 addr += sizeof(char *); 1717 } 1718 tprintf(fmt, count, count == 1 ? "" : "s"); 1719 } 1720 1721 int 1722 sys_execv(tcp) 1723 struct tcb *tcp; 1724 { 1725 if (entering(tcp)) { 1726 printpath(tcp, tcp->u_arg[0]); 1727 if (!verbose(tcp)) 1728 tprintf(", %#lx", tcp->u_arg[1]); 1729 #if 0 1730 else if (abbrev(tcp)) 1731 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]); 1732 #endif 1733 else { 1734 tprintf(", ["); 1735 printargv(tcp, tcp->u_arg[1]); 1736 tprintf("]"); 1737 } 1738 } 1739 return 0; 1740 } 1741 1742 int 1743 sys_execve(tcp) 1744 struct tcb *tcp; 1745 { 1746 if (entering(tcp)) { 1747 printpath(tcp, tcp->u_arg[0]); 1748 if (!verbose(tcp)) 1749 tprintf(", %#lx", tcp->u_arg[1]); 1750 #if 0 1751 else if (abbrev(tcp)) 1752 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]); 1753 #endif 1754 else { 1755 tprintf(", ["); 1756 printargv(tcp, tcp->u_arg[1]); 1757 tprintf("]"); 1758 } 1759 if (!verbose(tcp)) 1760 tprintf(", %#lx", tcp->u_arg[2]); 1761 else if (abbrev(tcp)) 1762 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]); 1763 else { 1764 tprintf(", ["); 1765 printargv(tcp, tcp->u_arg[2]); 1766 tprintf("]"); 1767 } 1768 } 1769 return 0; 1770 } 1771 1772 #if UNIXWARE > 2 1773 1774 int sys_rexecve(tcp) 1775 struct tcb *tcp; 1776 { 1777 if (entering (tcp)) { 1778 sys_execve (tcp); 1779 tprintf (", %ld", tcp->u_arg[3]); 1780 } 1781 return 0; 1782 } 1783 1784 #endif 1785 1786 int 1787 internal_exec(tcp) 1788 struct tcb *tcp; 1789 { 1790 #ifdef SUNOS4 1791 if (exiting(tcp) && !syserror(tcp) && followfork) 1792 fixvfork(tcp); 1793 #endif /* SUNOS4 */ 1794 #if defined LINUX && defined TCB_WAITEXECVE 1795 if (exiting(tcp) && syserror(tcp)) 1796 tcp->flags &= ~TCB_WAITEXECVE; 1797 else 1798 tcp->flags |= TCB_WAITEXECVE; 1799 #endif /* LINUX && TCB_WAITEXECVE */ 1800 return 0; 1801 } 1802 1803 #ifdef LINUX 1804 #ifndef __WNOTHREAD 1805 #define __WNOTHREAD 0x20000000 1806 #endif 1807 #ifndef __WALL 1808 #define __WALL 0x40000000 1809 #endif 1810 #ifndef __WCLONE 1811 #define __WCLONE 0x80000000 1812 #endif 1813 #endif /* LINUX */ 1814 1815 static const struct xlat wait4_options[] = { 1816 { WNOHANG, "WNOHANG" }, 1817 #ifndef WSTOPPED 1818 { WUNTRACED, "WUNTRACED" }, 1819 #endif 1820 #ifdef WEXITED 1821 { WEXITED, "WEXITED" }, 1822 #endif 1823 #ifdef WTRAPPED 1824 { WTRAPPED, "WTRAPPED" }, 1825 #endif 1826 #ifdef WSTOPPED 1827 { WSTOPPED, "WSTOPPED" }, 1828 #endif 1829 #ifdef WCONTINUED 1830 { WCONTINUED, "WCONTINUED" }, 1831 #endif 1832 #ifdef WNOWAIT 1833 { WNOWAIT, "WNOWAIT" }, 1834 #endif 1835 #ifdef __WCLONE 1836 { __WCLONE, "__WCLONE" }, 1837 #endif 1838 #ifdef __WALL 1839 { __WALL, "__WALL" }, 1840 #endif 1841 #ifdef __WNOTHREAD 1842 { __WNOTHREAD, "__WNOTHREAD" }, 1843 #endif 1844 { 0, NULL }, 1845 }; 1846 1847 #if !defined WCOREFLAG && defined WCOREFLG 1848 # define WCOREFLAG WCOREFLG 1849 #endif 1850 #ifndef WCOREFLAG 1851 #define WCOREFLAG 0x80 1852 #endif 1853 1854 #ifndef W_STOPCODE 1855 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f) 1856 #endif 1857 #ifndef W_EXITCODE 1858 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig)) 1859 #endif 1860 1861 static int 1862 printstatus(status) 1863 int status; 1864 { 1865 int exited = 0; 1866 1867 /* 1868 * Here is a tricky presentation problem. This solution 1869 * is still not entirely satisfactory but since there 1870 * are no wait status constructors it will have to do. 1871 */ 1872 if (WIFSTOPPED(status)) { 1873 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}", 1874 signame(WSTOPSIG(status))); 1875 status &= ~W_STOPCODE(WSTOPSIG(status)); 1876 } 1877 else if (WIFSIGNALED(status)) { 1878 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}", 1879 signame(WTERMSIG(status)), 1880 WCOREDUMP(status) ? " && WCOREDUMP(s)" : ""); 1881 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG); 1882 } 1883 else if (WIFEXITED(status)) { 1884 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}", 1885 WEXITSTATUS(status)); 1886 exited = 1; 1887 status &= ~W_EXITCODE(WEXITSTATUS(status), 0); 1888 } 1889 else { 1890 tprintf("[%#x]", status); 1891 return 0; 1892 } 1893 1894 if (status == 0) 1895 tprintf("]"); 1896 else 1897 tprintf(" | %#x]", status); 1898 1899 return exited; 1900 } 1901 1902 static int 1903 printwaitn(tcp, n, bitness) 1904 struct tcb *tcp; 1905 int n; 1906 int bitness; 1907 { 1908 int status; 1909 int exited = 0; 1910 1911 if (entering(tcp)) { 1912 tprintf("%ld, ", tcp->u_arg[0]); 1913 } else { 1914 /* status */ 1915 if (!tcp->u_arg[1]) 1916 tprintf("NULL"); 1917 else if (syserror(tcp) || tcp->u_rval == 0) 1918 tprintf("%#lx", tcp->u_arg[1]); 1919 else if (umove(tcp, tcp->u_arg[1], &status) < 0) 1920 tprintf("[?]"); 1921 else 1922 exited = printstatus(status); 1923 /* options */ 1924 tprintf(", "); 1925 printflags(wait4_options, tcp->u_arg[2], "W???"); 1926 if (n == 4) { 1927 tprintf(", "); 1928 /* usage */ 1929 if (!tcp->u_arg[3]) 1930 tprintf("NULL"); 1931 #ifdef LINUX 1932 else if (tcp->u_rval > 0) { 1933 #ifdef LINUX_64BIT 1934 if (bitness) 1935 printrusage32(tcp, tcp->u_arg[3]); 1936 else 1937 #endif 1938 printrusage(tcp, tcp->u_arg[3]); 1939 } 1940 #endif /* LINUX */ 1941 #ifdef SUNOS4 1942 else if (tcp->u_rval > 0 && exited) 1943 printrusage(tcp, tcp->u_arg[3]); 1944 #endif /* SUNOS4 */ 1945 else 1946 tprintf("%#lx", tcp->u_arg[3]); 1947 } 1948 } 1949 return 0; 1950 } 1951 1952 int 1953 internal_wait(tcp, flagarg) 1954 struct tcb *tcp; 1955 int flagarg; 1956 { 1957 int got_kids; 1958 1959 #ifdef TCB_CLONE_THREAD 1960 if (tcp->flags & TCB_CLONE_THREAD) 1961 /* The children we wait for are our parent's children. */ 1962 got_kids = (tcp->parent->nchildren 1963 > tcp->parent->nclone_detached); 1964 else 1965 got_kids = (tcp->nchildren > tcp->nclone_detached); 1966 #else 1967 got_kids = tcp->nchildren > 0; 1968 #endif 1969 1970 if (entering(tcp) && got_kids) { 1971 /* There are children that this parent should block for. 1972 But ptrace made us the parent of the traced children 1973 and the real parent will get ECHILD from the wait call. 1974 1975 XXX If we attached with strace -f -p PID, then there 1976 may be untraced dead children the parent could be reaping 1977 now, but we make him block. */ 1978 1979 /* ??? WTA: fix bug with hanging children */ 1980 1981 if (!(tcp->u_arg[flagarg] & WNOHANG)) { 1982 /* 1983 * There are traced children. We'll make the parent 1984 * block to avoid a false ECHILD error due to our 1985 * ptrace having stolen the children. However, 1986 * we shouldn't block if there are zombies to reap. 1987 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1) 1988 */ 1989 struct tcb *child = NULL; 1990 if (tcp->nzombies > 0 && 1991 (tcp->u_arg[0] == -1 || 1992 (child = pid2tcb(tcp->u_arg[0])) == NULL)) 1993 return 0; 1994 if (tcp->u_arg[0] > 0) { 1995 /* 1996 * If the parent waits for a specified child 1997 * PID, then it must get ECHILD right away 1998 * if that PID is not one of its children. 1999 * Make sure that the requested PID matches 2000 * one of the parent's children that we are 2001 * tracing, and don't suspend it otherwise. 2002 */ 2003 if (child == NULL) 2004 child = pid2tcb(tcp->u_arg[0]); 2005 if (child == NULL || child->parent != ( 2006 #ifdef TCB_CLONE_THREAD 2007 (tcp->flags & TCB_CLONE_THREAD) 2008 ? tcp->parent : 2009 #endif 2010 tcp)) 2011 return 0; 2012 } 2013 tcp->flags |= TCB_SUSPENDED; 2014 tcp->waitpid = tcp->u_arg[0]; 2015 #ifdef TCB_CLONE_THREAD 2016 if (tcp->flags & TCB_CLONE_THREAD) 2017 tcp->parent->nclone_waiting++; 2018 #endif 2019 } 2020 } 2021 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) { 2022 if (tcp->u_arg[flagarg] & WNOHANG) { 2023 /* We must force a fake result of 0 instead of 2024 the ECHILD error. */ 2025 extern int force_result(); 2026 return force_result(tcp, 0, 0); 2027 } 2028 } 2029 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 && 2030 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) { 2031 /* 2032 * We just reaped a child we don't know about, 2033 * presumably a zombie we already droptcb'd. 2034 */ 2035 tcp->nzombies--; 2036 } 2037 return 0; 2038 } 2039 2040 #ifdef SVR4 2041 2042 int 2043 sys_wait(tcp) 2044 struct tcb *tcp; 2045 { 2046 if (exiting(tcp)) { 2047 /* The library wrapper stuffs this into the user variable. */ 2048 if (!syserror(tcp)) 2049 printstatus(getrval2(tcp)); 2050 } 2051 return 0; 2052 } 2053 2054 #endif /* SVR4 */ 2055 2056 #ifdef FREEBSD 2057 int 2058 sys_wait(tcp) 2059 struct tcb *tcp; 2060 { 2061 int status; 2062 2063 if (exiting(tcp)) { 2064 if (!syserror(tcp)) { 2065 if (umove(tcp, tcp->u_arg[0], &status) < 0) 2066 tprintf("%#lx", tcp->u_arg[0]); 2067 else 2068 printstatus(status); 2069 } 2070 } 2071 return 0; 2072 } 2073 #endif 2074 2075 int 2076 sys_waitpid(tcp) 2077 struct tcb *tcp; 2078 { 2079 return printwaitn(tcp, 3, 0); 2080 } 2081 2082 int 2083 sys_wait4(tcp) 2084 struct tcb *tcp; 2085 { 2086 return printwaitn(tcp, 4, 0); 2087 } 2088 2089 #ifdef ALPHA 2090 int 2091 sys_osf_wait4(tcp) 2092 struct tcb *tcp; 2093 { 2094 return printwaitn(tcp, 4, 1); 2095 } 2096 #endif 2097 2098 #if defined SVR4 || defined LINUX 2099 2100 static const struct xlat waitid_types[] = { 2101 { P_PID, "P_PID" }, 2102 #ifdef P_PPID 2103 { P_PPID, "P_PPID" }, 2104 #endif 2105 { P_PGID, "P_PGID" }, 2106 #ifdef P_SID 2107 { P_SID, "P_SID" }, 2108 #endif 2109 #ifdef P_CID 2110 { P_CID, "P_CID" }, 2111 #endif 2112 #ifdef P_UID 2113 { P_UID, "P_UID" }, 2114 #endif 2115 #ifdef P_GID 2116 { P_GID, "P_GID" }, 2117 #endif 2118 { P_ALL, "P_ALL" }, 2119 #ifdef P_LWPID 2120 { P_LWPID, "P_LWPID" }, 2121 #endif 2122 { 0, NULL }, 2123 }; 2124 2125 int 2126 sys_waitid(tcp) 2127 struct tcb *tcp; 2128 { 2129 siginfo_t si; 2130 int exited; 2131 2132 if (entering(tcp)) { 2133 printxval(waitid_types, tcp->u_arg[0], "P_???"); 2134 tprintf(", %ld, ", tcp->u_arg[1]); 2135 } 2136 else { 2137 /* siginfo */ 2138 exited = 0; 2139 if (!tcp->u_arg[2]) 2140 tprintf("NULL"); 2141 else if (syserror(tcp)) 2142 tprintf("%#lx", tcp->u_arg[2]); 2143 else if (umove(tcp, tcp->u_arg[2], &si) < 0) 2144 tprintf("{???}"); 2145 else 2146 printsiginfo(&si, verbose (tcp)); 2147 /* options */ 2148 tprintf(", "); 2149 printflags(wait4_options, tcp->u_arg[3], "W???"); 2150 if (tcp->u_nargs > 4) { 2151 /* usage */ 2152 tprintf(", "); 2153 if (!tcp->u_arg[4]) 2154 tprintf("NULL"); 2155 else if (tcp->u_error) 2156 tprintf("%#lx", tcp->u_arg[4]); 2157 else 2158 printrusage(tcp, tcp->u_arg[4]); 2159 } 2160 } 2161 return 0; 2162 } 2163 2164 #endif /* SVR4 or LINUX */ 2165 2166 int 2167 sys_alarm(tcp) 2168 struct tcb *tcp; 2169 { 2170 if (entering(tcp)) 2171 tprintf("%lu", tcp->u_arg[0]); 2172 return 0; 2173 } 2174 2175 int 2176 sys_uname(tcp) 2177 struct tcb *tcp; 2178 { 2179 struct utsname uname; 2180 2181 if (exiting(tcp)) { 2182 if (syserror(tcp) || !verbose(tcp)) 2183 tprintf("%#lx", tcp->u_arg[0]); 2184 else if (umove(tcp, tcp->u_arg[0], &uname) < 0) 2185 tprintf("{...}"); 2186 else if (!abbrev(tcp)) { 2187 2188 tprintf("{sysname=\"%s\", nodename=\"%s\", ", 2189 uname.sysname, uname.nodename); 2190 tprintf("release=\"%s\", version=\"%s\", ", 2191 uname.release, uname.version); 2192 tprintf("machine=\"%s\"", uname.machine); 2193 #ifdef LINUX 2194 #ifndef __GLIBC__ 2195 tprintf(", domainname=\"%s\"", uname.domainname); 2196 #endif /* __GLIBC__ */ 2197 #endif /* LINUX */ 2198 tprintf("}"); 2199 } 2200 else 2201 tprintf("{sys=\"%s\", node=\"%s\", ...}", 2202 uname.sysname, uname.nodename); 2203 } 2204 return 0; 2205 } 2206 2207 #ifndef SVR4 2208 2209 static const struct xlat ptrace_cmds[] = { 2210 #ifndef FREEBSD 2211 { PTRACE_TRACEME, "PTRACE_TRACEME" }, 2212 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", }, 2213 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", }, 2214 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", }, 2215 { PTRACE_POKETEXT, "PTRACE_POKETEXT", }, 2216 { PTRACE_POKEDATA, "PTRACE_POKEDATA", }, 2217 { PTRACE_POKEUSER, "PTRACE_POKEUSER", }, 2218 { PTRACE_CONT, "PTRACE_CONT" }, 2219 { PTRACE_KILL, "PTRACE_KILL" }, 2220 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" }, 2221 { PTRACE_ATTACH, "PTRACE_ATTACH" }, 2222 { PTRACE_DETACH, "PTRACE_DETACH" }, 2223 #ifdef PTRACE_GETREGS 2224 { PTRACE_GETREGS, "PTRACE_GETREGS" }, 2225 #endif 2226 #ifdef PTRACE_SETREGS 2227 { PTRACE_SETREGS, "PTRACE_SETREGS" }, 2228 #endif 2229 #ifdef PTRACE_GETFPREGS 2230 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", }, 2231 #endif 2232 #ifdef PTRACE_SETFPREGS 2233 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", }, 2234 #endif 2235 #ifdef PTRACE_GETFPXREGS 2236 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", }, 2237 #endif 2238 #ifdef PTRACE_SETFPXREGS 2239 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", }, 2240 #endif 2241 #ifdef PTRACE_GETVRREGS 2242 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", }, 2243 #endif 2244 #ifdef PTRACE_SETVRREGS 2245 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", }, 2246 #endif 2247 #ifdef SUNOS4 2248 { PTRACE_READDATA, "PTRACE_READDATA" }, 2249 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" }, 2250 { PTRACE_READTEXT, "PTRACE_READTEXT" }, 2251 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" }, 2252 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" }, 2253 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" }, 2254 #ifdef SPARC 2255 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" }, 2256 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" }, 2257 #else /* !SPARC */ 2258 { PTRACE_22, "PTRACE_PTRACE_22" }, 2259 { PTRACE_23, "PTRACE_PTRACE_23" }, 2260 #endif /* !SPARC */ 2261 #endif /* SUNOS4 */ 2262 { PTRACE_SYSCALL, "PTRACE_SYSCALL" }, 2263 #ifdef SUNOS4 2264 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" }, 2265 #ifdef I386 2266 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" }, 2267 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" }, 2268 { PTRACE_CLRDR7, "PTRACE_CLRDR7" }, 2269 #else /* !I386 */ 2270 { PTRACE_26, "PTRACE_26" }, 2271 { PTRACE_27, "PTRACE_27" }, 2272 { PTRACE_28, "PTRACE_28" }, 2273 #endif /* !I386 */ 2274 { PTRACE_GETUCODE, "PTRACE_GETUCODE" }, 2275 #endif /* SUNOS4 */ 2276 #else /* FREEBSD */ 2277 { PT_TRACE_ME, "PT_TRACE_ME" }, 2278 { PT_READ_I, "PT_READ_I" }, 2279 { PT_READ_D, "PT_READ_D" }, 2280 { PT_WRITE_I, "PT_WRITE_I" }, 2281 { PT_WRITE_D, "PT_WRITE_D" }, 2282 #ifdef PT_READ_U 2283 { PT_READ_U, "PT_READ_U" }, 2284 #endif 2285 { PT_CONTINUE, "PT_CONTINUE" }, 2286 { PT_KILL, "PT_KILL" }, 2287 { PT_STEP, "PT_STEP" }, 2288 { PT_ATTACH, "PT_ATTACH" }, 2289 { PT_DETACH, "PT_DETACH" }, 2290 { PT_GETREGS, "PT_GETREGS" }, 2291 { PT_SETREGS, "PT_SETREGS" }, 2292 { PT_GETFPREGS, "PT_GETFPREGS" }, 2293 { PT_SETFPREGS, "PT_SETFPREGS" }, 2294 { PT_GETDBREGS, "PT_GETDBREGS" }, 2295 { PT_SETDBREGS, "PT_SETDBREGS" }, 2296 #endif /* FREEBSD */ 2297 { 0, NULL }, 2298 }; 2299 2300 #ifndef FREEBSD 2301 #ifndef SUNOS4_KERNEL_ARCH_KLUDGE 2302 static 2303 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */ 2304 const struct xlat struct_user_offsets[] = { 2305 #ifdef LINUX 2306 #if defined(S390) || defined(S390X) 2307 { PT_PSWMASK, "psw_mask" }, 2308 { PT_PSWADDR, "psw_addr" }, 2309 { PT_GPR0, "gpr0" }, 2310 { PT_GPR1, "gpr1" }, 2311 { PT_GPR2, "gpr2" }, 2312 { PT_GPR3, "gpr3" }, 2313 { PT_GPR4, "gpr4" }, 2314 { PT_GPR5, "gpr5" }, 2315 { PT_GPR6, "gpr6" }, 2316 { PT_GPR7, "gpr7" }, 2317 { PT_GPR8, "gpr8" }, 2318 { PT_GPR9, "gpr9" }, 2319 { PT_GPR10, "gpr10" }, 2320 { PT_GPR11, "gpr11" }, 2321 { PT_GPR12, "gpr12" }, 2322 { PT_GPR13, "gpr13" }, 2323 { PT_GPR14, "gpr14" }, 2324 { PT_GPR15, "gpr15" }, 2325 { PT_ACR0, "acr0" }, 2326 { PT_ACR1, "acr1" }, 2327 { PT_ACR2, "acr2" }, 2328 { PT_ACR3, "acr3" }, 2329 { PT_ACR4, "acr4" }, 2330 { PT_ACR5, "acr5" }, 2331 { PT_ACR6, "acr6" }, 2332 { PT_ACR7, "acr7" }, 2333 { PT_ACR8, "acr8" }, 2334 { PT_ACR9, "acr9" }, 2335 { PT_ACR10, "acr10" }, 2336 { PT_ACR11, "acr11" }, 2337 { PT_ACR12, "acr12" }, 2338 { PT_ACR13, "acr13" }, 2339 { PT_ACR14, "acr14" }, 2340 { PT_ACR15, "acr15" }, 2341 { PT_ORIGGPR2, "orig_gpr2" }, 2342 { PT_FPC, "fpc" }, 2343 #if defined(S390) 2344 { PT_FPR0_HI, "fpr0.hi" }, 2345 { PT_FPR0_LO, "fpr0.lo" }, 2346 { PT_FPR1_HI, "fpr1.hi" }, 2347 { PT_FPR1_LO, "fpr1.lo" }, 2348 { PT_FPR2_HI, "fpr2.hi" }, 2349 { PT_FPR2_LO, "fpr2.lo" }, 2350 { PT_FPR3_HI, "fpr3.hi" }, 2351 { PT_FPR3_LO, "fpr3.lo" }, 2352 { PT_FPR4_HI, "fpr4.hi" }, 2353 { PT_FPR4_LO, "fpr4.lo" }, 2354 { PT_FPR5_HI, "fpr5.hi" }, 2355 { PT_FPR5_LO, "fpr5.lo" }, 2356 { PT_FPR6_HI, "fpr6.hi" }, 2357 { PT_FPR6_LO, "fpr6.lo" }, 2358 { PT_FPR7_HI, "fpr7.hi" }, 2359 { PT_FPR7_LO, "fpr7.lo" }, 2360 { PT_FPR8_HI, "fpr8.hi" }, 2361 { PT_FPR8_LO, "fpr8.lo" }, 2362 { PT_FPR9_HI, "fpr9.hi" }, 2363 { PT_FPR9_LO, "fpr9.lo" }, 2364 { PT_FPR10_HI, "fpr10.hi" }, 2365 { PT_FPR10_LO, "fpr10.lo" }, 2366 { PT_FPR11_HI, "fpr11.hi" }, 2367 { PT_FPR11_LO, "fpr11.lo" }, 2368 { PT_FPR12_HI, "fpr12.hi" }, 2369 { PT_FPR12_LO, "fpr12.lo" }, 2370 { PT_FPR13_HI, "fpr13.hi" }, 2371 { PT_FPR13_LO, "fpr13.lo" }, 2372 { PT_FPR14_HI, "fpr14.hi" }, 2373 { PT_FPR14_LO, "fpr14.lo" }, 2374 { PT_FPR15_HI, "fpr15.hi" }, 2375 { PT_FPR15_LO, "fpr15.lo" }, 2376 #endif 2377 #if defined(S390X) 2378 { PT_FPR0, "fpr0" }, 2379 { PT_FPR1, "fpr1" }, 2380 { PT_FPR2, "fpr2" }, 2381 { PT_FPR3, "fpr3" }, 2382 { PT_FPR4, "fpr4" }, 2383 { PT_FPR5, "fpr5" }, 2384 { PT_FPR6, "fpr6" }, 2385 { PT_FPR7, "fpr7" }, 2386 { PT_FPR8, "fpr8" }, 2387 { PT_FPR9, "fpr9" }, 2388 { PT_FPR10, "fpr10" }, 2389 { PT_FPR11, "fpr11" }, 2390 { PT_FPR12, "fpr12" }, 2391 { PT_FPR13, "fpr13" }, 2392 { PT_FPR14, "fpr14" }, 2393 { PT_FPR15, "fpr15" }, 2394 #endif 2395 { PT_CR_9, "cr9" }, 2396 { PT_CR_10, "cr10" }, 2397 { PT_CR_11, "cr11" }, 2398 { PT_IEEE_IP, "ieee_exception_ip" }, 2399 #endif 2400 #if defined(SPARC) 2401 /* XXX No support for these offsets yet. */ 2402 #elif defined(HPPA) 2403 /* XXX No support for these offsets yet. */ 2404 #elif defined(POWERPC) 2405 #ifndef PT_ORIG_R3 2406 #define PT_ORIG_R3 34 2407 #endif 2408 #define REGSIZE (sizeof(unsigned long)) 2409 { REGSIZE*PT_R0, "r0" }, 2410 { REGSIZE*PT_R1, "r1" }, 2411 { REGSIZE*PT_R2, "r2" }, 2412 { REGSIZE*PT_R3, "r3" }, 2413 { REGSIZE*PT_R4, "r4" }, 2414 { REGSIZE*PT_R5, "r5" }, 2415 { REGSIZE*PT_R6, "r6" }, 2416 { REGSIZE*PT_R7, "r7" }, 2417 { REGSIZE*PT_R8, "r8" }, 2418 { REGSIZE*PT_R9, "r9" }, 2419 { REGSIZE*PT_R10, "r10" }, 2420 { REGSIZE*PT_R11, "r11" }, 2421 { REGSIZE*PT_R12, "r12" }, 2422 { REGSIZE*PT_R13, "r13" }, 2423 { REGSIZE*PT_R14, "r14" }, 2424 { REGSIZE*PT_R15, "r15" }, 2425 { REGSIZE*PT_R16, "r16" }, 2426 { REGSIZE*PT_R17, "r17" }, 2427 { REGSIZE*PT_R18, "r18" }, 2428 { REGSIZE*PT_R19, "r19" }, 2429 { REGSIZE*PT_R20, "r20" }, 2430 { REGSIZE*PT_R21, "r21" }, 2431 { REGSIZE*PT_R22, "r22" }, 2432 { REGSIZE*PT_R23, "r23" }, 2433 { REGSIZE*PT_R24, "r24" }, 2434 { REGSIZE*PT_R25, "r25" }, 2435 { REGSIZE*PT_R26, "r26" }, 2436 { REGSIZE*PT_R27, "r27" }, 2437 { REGSIZE*PT_R28, "r28" }, 2438 { REGSIZE*PT_R29, "r29" }, 2439 { REGSIZE*PT_R30, "r30" }, 2440 { REGSIZE*PT_R31, "r31" }, 2441 { REGSIZE*PT_NIP, "NIP" }, 2442 { REGSIZE*PT_MSR, "MSR" }, 2443 { REGSIZE*PT_ORIG_R3, "ORIG_R3" }, 2444 { REGSIZE*PT_CTR, "CTR" }, 2445 { REGSIZE*PT_LNK, "LNK" }, 2446 { REGSIZE*PT_XER, "XER" }, 2447 { REGSIZE*PT_CCR, "CCR" }, 2448 { REGSIZE*PT_FPR0, "FPR0" }, 2449 #undef REGSIZE 2450 #else 2451 #ifdef ALPHA 2452 { 0, "r0" }, 2453 { 1, "r1" }, 2454 { 2, "r2" }, 2455 { 3, "r3" }, 2456 { 4, "r4" }, 2457 { 5, "r5" }, 2458 { 6, "r6" }, 2459 { 7, "r7" }, 2460 { 8, "r8" }, 2461 { 9, "r9" }, 2462 { 10, "r10" }, 2463 { 11, "r11" }, 2464 { 12, "r12" }, 2465 { 13, "r13" }, 2466 { 14, "r14" }, 2467 { 15, "r15" }, 2468 { 16, "r16" }, 2469 { 17, "r17" }, 2470 { 18, "r18" }, 2471 { 19, "r19" }, 2472 { 20, "r20" }, 2473 { 21, "r21" }, 2474 { 22, "r22" }, 2475 { 23, "r23" }, 2476 { 24, "r24" }, 2477 { 25, "r25" }, 2478 { 26, "r26" }, 2479 { 27, "r27" }, 2480 { 28, "r28" }, 2481 { 29, "gp" }, 2482 { 30, "fp" }, 2483 { 31, "zero" }, 2484 { 32, "fp0" }, 2485 { 33, "fp" }, 2486 { 34, "fp2" }, 2487 { 35, "fp3" }, 2488 { 36, "fp4" }, 2489 { 37, "fp5" }, 2490 { 38, "fp6" }, 2491 { 39, "fp7" }, 2492 { 40, "fp8" }, 2493 { 41, "fp9" }, 2494 { 42, "fp10" }, 2495 { 43, "fp11" }, 2496 { 44, "fp12" }, 2497 { 45, "fp13" }, 2498 { 46, "fp14" }, 2499 { 47, "fp15" }, 2500 { 48, "fp16" }, 2501 { 49, "fp17" }, 2502 { 50, "fp18" }, 2503 { 51, "fp19" }, 2504 { 52, "fp20" }, 2505 { 53, "fp21" }, 2506 { 54, "fp22" }, 2507 { 55, "fp23" }, 2508 { 56, "fp24" }, 2509 { 57, "fp25" }, 2510 { 58, "fp26" }, 2511 { 59, "fp27" }, 2512 { 60, "fp28" }, 2513 { 61, "fp29" }, 2514 { 62, "fp30" }, 2515 { 63, "fp31" }, 2516 { 64, "pc" }, 2517 #else /* !ALPHA */ 2518 #ifdef IA64 2519 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" }, 2520 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" }, 2521 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" }, 2522 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" }, 2523 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" }, 2524 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" }, 2525 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" }, 2526 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" }, 2527 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" }, 2528 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" }, 2529 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" }, 2530 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" }, 2531 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" }, 2532 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" }, 2533 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" }, 2534 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" }, 2535 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" }, 2536 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" }, 2537 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" }, 2538 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" }, 2539 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" }, 2540 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" }, 2541 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" }, 2542 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" }, 2543 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" }, 2544 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" }, 2545 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" }, 2546 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" }, 2547 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" }, 2548 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" }, 2549 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" }, 2550 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" }, 2551 /* switch stack: */ 2552 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" }, 2553 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" }, 2554 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" }, 2555 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" }, 2556 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" }, 2557 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" }, 2558 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" }, 2559 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" }, 2560 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" }, 2561 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" }, 2562 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" }, 2563 { PT_B4, "b4" }, { PT_B5, "b5" }, 2564 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" }, 2565 /* pt_regs */ 2566 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" }, 2567 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" }, 2568 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" }, 2569 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" }, 2570 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" }, 2571 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" }, 2572 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" }, 2573 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" }, 2574 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" }, 2575 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" }, 2576 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" }, 2577 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" }, 2578 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" }, 2579 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" }, 2580 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" }, 2581 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" }, 2582 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" }, 2583 # ifdef PT_AR_CSD 2584 { PT_AR_CSD, "ar.csd" }, 2585 # endif 2586 # ifdef PT_AR_SSD 2587 { PT_AR_SSD, "ar.ssd" }, 2588 # endif 2589 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" }, 2590 #else /* !IA64 */ 2591 #ifdef I386 2592 { 4*EBX, "4*EBX" }, 2593 { 4*ECX, "4*ECX" }, 2594 { 4*EDX, "4*EDX" }, 2595 { 4*ESI, "4*ESI" }, 2596 { 4*EDI, "4*EDI" }, 2597 { 4*EBP, "4*EBP" }, 2598 { 4*EAX, "4*EAX" }, 2599 { 4*DS, "4*DS" }, 2600 { 4*ES, "4*ES" }, 2601 { 4*FS, "4*FS" }, 2602 { 4*GS, "4*GS" }, 2603 { 4*ORIG_EAX, "4*ORIG_EAX" }, 2604 { 4*EIP, "4*EIP" }, 2605 { 4*CS, "4*CS" }, 2606 { 4*EFL, "4*EFL" }, 2607 { 4*UESP, "4*UESP" }, 2608 { 4*SS, "4*SS" }, 2609 #else /* !I386 */ 2610 #ifdef X86_64 2611 { 8*R15, "8*R15" }, 2612 { 8*R14, "8*R14" }, 2613 { 8*R13, "8*R13" }, 2614 { 8*R12, "8*R12" }, 2615 { 8*RBP, "8*RBP" }, 2616 { 8*RBX, "8*RBX" }, 2617 { 8*R11, "8*R11" }, 2618 { 8*R10, "8*R10" }, 2619 { 8*R9, "8*R9" }, 2620 { 8*R8, "8*R8" }, 2621 { 8*RAX, "8*RAX" }, 2622 { 8*RCX, "8*RCX" }, 2623 { 8*RDX, "8*RDX" }, 2624 { 8*RSI, "8*RSI" }, 2625 { 8*RDI, "8*RDI" }, 2626 #if 0 2627 { DS, "DS" }, 2628 { ES, "ES" }, 2629 { FS, "FS" }, 2630 { GS, "GS" }, 2631 #endif 2632 { 8*ORIG_RAX, "8*ORIG_RAX" }, 2633 { 8*RIP, "8*RIP" }, 2634 { 8*CS, "8*CS" }, 2635 { 8*EFLAGS, "8*EFL" }, 2636 { 8*RSP, "8*RSP" }, 2637 { 8*SS, "8*SS" }, 2638 #endif 2639 #ifdef M68K 2640 { 4*PT_D1, "4*PT_D1" }, 2641 { 4*PT_D2, "4*PT_D2" }, 2642 { 4*PT_D3, "4*PT_D3" }, 2643 { 4*PT_D4, "4*PT_D4" }, 2644 { 4*PT_D5, "4*PT_D5" }, 2645 { 4*PT_D6, "4*PT_D6" }, 2646 { 4*PT_D7, "4*PT_D7" }, 2647 { 4*PT_A0, "4*PT_A0" }, 2648 { 4*PT_A1, "4*PT_A1" }, 2649 { 4*PT_A2, "4*PT_A2" }, 2650 { 4*PT_A3, "4*PT_A3" }, 2651 { 4*PT_A4, "4*PT_A4" }, 2652 { 4*PT_A5, "4*PT_A5" }, 2653 { 4*PT_A6, "4*PT_A6" }, 2654 { 4*PT_D0, "4*PT_D0" }, 2655 { 4*PT_USP, "4*PT_USP" }, 2656 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" }, 2657 { 4*PT_SR, "4*PT_SR" }, 2658 { 4*PT_PC, "4*PT_PC" }, 2659 #endif /* M68K */ 2660 #endif /* !I386 */ 2661 #ifdef SH 2662 { 4*REG_REG0, "4*REG_REG0" }, 2663 { 4*(REG_REG0+1), "4*REG_REG1" }, 2664 { 4*(REG_REG0+2), "4*REG_REG2" }, 2665 { 4*(REG_REG0+3), "4*REG_REG3" }, 2666 { 4*(REG_REG0+4), "4*REG_REG4" }, 2667 { 4*(REG_REG0+5), "4*REG_REG5" }, 2668 { 4*(REG_REG0+6), "4*REG_REG6" }, 2669 { 4*(REG_REG0+7), "4*REG_REG7" }, 2670 { 4*(REG_REG0+8), "4*REG_REG8" }, 2671 { 4*(REG_REG0+9), "4*REG_REG9" }, 2672 { 4*(REG_REG0+10), "4*REG_REG10" }, 2673 { 4*(REG_REG0+11), "4*REG_REG11" }, 2674 { 4*(REG_REG0+12), "4*REG_REG12" }, 2675 { 4*(REG_REG0+13), "4*REG_REG13" }, 2676 { 4*(REG_REG0+14), "4*REG_REG14" }, 2677 { 4*REG_REG15, "4*REG_REG15" }, 2678 { 4*REG_PC, "4*REG_PC" }, 2679 { 4*REG_PR, "4*REG_PR" }, 2680 { 4*REG_SR, "4*REG_SR" }, 2681 { 4*REG_GBR, "4*REG_GBR" }, 2682 { 4*REG_MACH, "4*REG_MACH" }, 2683 { 4*REG_MACL, "4*REG_MACL" }, 2684 { 4*REG_SYSCALL, "4*REG_SYSCALL" }, 2685 { 4*REG_FPUL, "4*REG_FPUL" }, 2686 { 4*REG_FPREG0, "4*REG_FPREG0" }, 2687 { 4*(REG_FPREG0+1), "4*REG_FPREG1" }, 2688 { 4*(REG_FPREG0+2), "4*REG_FPREG2" }, 2689 { 4*(REG_FPREG0+3), "4*REG_FPREG3" }, 2690 { 4*(REG_FPREG0+4), "4*REG_FPREG4" }, 2691 { 4*(REG_FPREG0+5), "4*REG_FPREG5" }, 2692 { 4*(REG_FPREG0+6), "4*REG_FPREG6" }, 2693 { 4*(REG_FPREG0+7), "4*REG_FPREG7" }, 2694 { 4*(REG_FPREG0+8), "4*REG_FPREG8" }, 2695 { 4*(REG_FPREG0+9), "4*REG_FPREG9" }, 2696 { 4*(REG_FPREG0+10), "4*REG_FPREG10" }, 2697 { 4*(REG_FPREG0+11), "4*REG_FPREG11" }, 2698 { 4*(REG_FPREG0+12), "4*REG_FPREG12" }, 2699 { 4*(REG_FPREG0+13), "4*REG_FPREG13" }, 2700 { 4*(REG_FPREG0+14), "4*REG_FPREG14" }, 2701 { 4*REG_FPREG15, "4*REG_FPREG15" }, 2702 #ifdef REG_XDREG0 2703 { 4*REG_XDREG0, "4*REG_XDREG0" }, 2704 { 4*(REG_XDREG0+2), "4*REG_XDREG2" }, 2705 { 4*(REG_XDREG0+4), "4*REG_XDREG4" }, 2706 { 4*(REG_XDREG0+6), "4*REG_XDREG6" }, 2707 { 4*(REG_XDREG0+8), "4*REG_XDREG8" }, 2708 { 4*(REG_XDREG0+10), "4*REG_XDREG10" }, 2709 { 4*(REG_XDREG0+12), "4*REG_XDREG12" }, 2710 { 4*REG_XDREG14, "4*REG_XDREG14" }, 2711 #endif 2712 { 4*REG_FPSCR, "4*REG_FPSCR" }, 2713 #endif /* SH */ 2714 #ifdef SH64 2715 { 0, "PC(L)" }, 2716 { 4, "PC(U)" }, 2717 { 8, "SR(L)" }, 2718 { 12, "SR(U)" }, 2719 { 16, "syscall no.(L)" }, 2720 { 20, "syscall_no.(U)" }, 2721 { 24, "R0(L)" }, 2722 { 28, "R0(U)" }, 2723 { 32, "R1(L)" }, 2724 { 36, "R1(U)" }, 2725 { 40, "R2(L)" }, 2726 { 44, "R2(U)" }, 2727 { 48, "R3(L)" }, 2728 { 52, "R3(U)" }, 2729 { 56, "R4(L)" }, 2730 { 60, "R4(U)" }, 2731 { 64, "R5(L)" }, 2732 { 68, "R5(U)" }, 2733 { 72, "R6(L)" }, 2734 { 76, "R6(U)" }, 2735 { 80, "R7(L)" }, 2736 { 84, "R7(U)" }, 2737 { 88, "R8(L)" }, 2738 { 92, "R8(U)" }, 2739 { 96, "R9(L)" }, 2740 { 100, "R9(U)" }, 2741 { 104, "R10(L)" }, 2742 { 108, "R10(U)" }, 2743 { 112, "R11(L)" }, 2744 { 116, "R11(U)" }, 2745 { 120, "R12(L)" }, 2746 { 124, "R12(U)" }, 2747 { 128, "R13(L)" }, 2748 { 132, "R13(U)" }, 2749 { 136, "R14(L)" }, 2750 { 140, "R14(U)" }, 2751 { 144, "R15(L)" }, 2752 { 148, "R15(U)" }, 2753 { 152, "R16(L)" }, 2754 { 156, "R16(U)" }, 2755 { 160, "R17(L)" }, 2756 { 164, "R17(U)" }, 2757 { 168, "R18(L)" }, 2758 { 172, "R18(U)" }, 2759 { 176, "R19(L)" }, 2760 { 180, "R19(U)" }, 2761 { 184, "R20(L)" }, 2762 { 188, "R20(U)" }, 2763 { 192, "R21(L)" }, 2764 { 196, "R21(U)" }, 2765 { 200, "R22(L)" }, 2766 { 204, "R22(U)" }, 2767 { 208, "R23(L)" }, 2768 { 212, "R23(U)" }, 2769 { 216, "R24(L)" }, 2770 { 220, "R24(U)" }, 2771 { 224, "R25(L)" }, 2772 { 228, "R25(U)" }, 2773 { 232, "R26(L)" }, 2774 { 236, "R26(U)" }, 2775 { 240, "R27(L)" }, 2776 { 244, "R27(U)" }, 2777 { 248, "R28(L)" }, 2778 { 252, "R28(U)" }, 2779 { 256, "R29(L)" }, 2780 { 260, "R29(U)" }, 2781 { 264, "R30(L)" }, 2782 { 268, "R30(U)" }, 2783 { 272, "R31(L)" }, 2784 { 276, "R31(U)" }, 2785 { 280, "R32(L)" }, 2786 { 284, "R32(U)" }, 2787 { 288, "R33(L)" }, 2788 { 292, "R33(U)" }, 2789 { 296, "R34(L)" }, 2790 { 300, "R34(U)" }, 2791 { 304, "R35(L)" }, 2792 { 308, "R35(U)" }, 2793 { 312, "R36(L)" }, 2794 { 316, "R36(U)" }, 2795 { 320, "R37(L)" }, 2796 { 324, "R37(U)" }, 2797 { 328, "R38(L)" }, 2798 { 332, "R38(U)" }, 2799 { 336, "R39(L)" }, 2800 { 340, "R39(U)" }, 2801 { 344, "R40(L)" }, 2802 { 348, "R40(U)" }, 2803 { 352, "R41(L)" }, 2804 { 356, "R41(U)" }, 2805 { 360, "R42(L)" }, 2806 { 364, "R42(U)" }, 2807 { 368, "R43(L)" }, 2808 { 372, "R43(U)" }, 2809 { 376, "R44(L)" }, 2810 { 380, "R44(U)" }, 2811 { 384, "R45(L)" }, 2812 { 388, "R45(U)" }, 2813 { 392, "R46(L)" }, 2814 { 396, "R46(U)" }, 2815 { 400, "R47(L)" }, 2816 { 404, "R47(U)" }, 2817 { 408, "R48(L)" }, 2818 { 412, "R48(U)" }, 2819 { 416, "R49(L)" }, 2820 { 420, "R49(U)" }, 2821 { 424, "R50(L)" }, 2822 { 428, "R50(U)" }, 2823 { 432, "R51(L)" }, 2824 { 436, "R51(U)" }, 2825 { 440, "R52(L)" }, 2826 { 444, "R52(U)" }, 2827 { 448, "R53(L)" }, 2828 { 452, "R53(U)" }, 2829 { 456, "R54(L)" }, 2830 { 460, "R54(U)" }, 2831 { 464, "R55(L)" }, 2832 { 468, "R55(U)" }, 2833 { 472, "R56(L)" }, 2834 { 476, "R56(U)" }, 2835 { 480, "R57(L)" }, 2836 { 484, "R57(U)" }, 2837 { 488, "R58(L)" }, 2838 { 492, "R58(U)" }, 2839 { 496, "R59(L)" }, 2840 { 500, "R59(U)" }, 2841 { 504, "R60(L)" }, 2842 { 508, "R60(U)" }, 2843 { 512, "R61(L)" }, 2844 { 516, "R61(U)" }, 2845 { 520, "R62(L)" }, 2846 { 524, "R62(U)" }, 2847 { 528, "TR0(L)" }, 2848 { 532, "TR0(U)" }, 2849 { 536, "TR1(L)" }, 2850 { 540, "TR1(U)" }, 2851 { 544, "TR2(L)" }, 2852 { 548, "TR2(U)" }, 2853 { 552, "TR3(L)" }, 2854 { 556, "TR3(U)" }, 2855 { 560, "TR4(L)" }, 2856 { 564, "TR4(U)" }, 2857 { 568, "TR5(L)" }, 2858 { 572, "TR5(U)" }, 2859 { 576, "TR6(L)" }, 2860 { 580, "TR6(U)" }, 2861 { 584, "TR7(L)" }, 2862 { 588, "TR7(U)" }, 2863 /* This entry is in case pt_regs contains dregs (depends on 2864 the kernel build options). */ 2865 { uoff(regs), "offsetof(struct user, regs)" }, 2866 { uoff(fpu), "offsetof(struct user, fpu)" }, 2867 #endif 2868 #ifdef ARM 2869 { uoff(regs.ARM_r0), "r0" }, 2870 { uoff(regs.ARM_r1), "r1" }, 2871 { uoff(regs.ARM_r2), "r2" }, 2872 { uoff(regs.ARM_r3), "r3" }, 2873 { uoff(regs.ARM_r4), "r4" }, 2874 { uoff(regs.ARM_r5), "r5" }, 2875 { uoff(regs.ARM_r6), "r6" }, 2876 { uoff(regs.ARM_r7), "r7" }, 2877 { uoff(regs.ARM_r8), "r8" }, 2878 { uoff(regs.ARM_r9), "r9" }, 2879 { uoff(regs.ARM_r10), "r10" }, 2880 { uoff(regs.ARM_fp), "fp" }, 2881 { uoff(regs.ARM_ip), "ip" }, 2882 { uoff(regs.ARM_sp), "sp" }, 2883 { uoff(regs.ARM_lr), "lr" }, 2884 { uoff(regs.ARM_pc), "pc" }, 2885 { uoff(regs.ARM_cpsr), "cpsr" }, 2886 #endif 2887 2888 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) 2889 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" }, 2890 #endif 2891 #if defined(I386) || defined(X86_64) 2892 { uoff(i387), "offsetof(struct user, i387)" }, 2893 #else /* !I386 */ 2894 #ifdef M68K 2895 { uoff(m68kfp), "offsetof(struct user, m68kfp)" }, 2896 #endif /* M68K */ 2897 #endif /* !I386 */ 2898 { uoff(u_tsize), "offsetof(struct user, u_tsize)" }, 2899 { uoff(u_dsize), "offsetof(struct user, u_dsize)" }, 2900 { uoff(u_ssize), "offsetof(struct user, u_ssize)" }, 2901 #if !defined(SPARC64) 2902 { uoff(start_code), "offsetof(struct user, start_code)" }, 2903 #endif 2904 #ifdef SH64 2905 { uoff(start_data), "offsetof(struct user, start_data)" }, 2906 #endif 2907 #if !defined(SPARC64) 2908 { uoff(start_stack), "offsetof(struct user, start_stack)" }, 2909 #endif 2910 { uoff(signal), "offsetof(struct user, signal)" }, 2911 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64) 2912 { uoff(reserved), "offsetof(struct user, reserved)" }, 2913 #endif 2914 #if !defined(SPARC64) 2915 { uoff(u_ar0), "offsetof(struct user, u_ar0)" }, 2916 #endif 2917 #if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) 2918 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" }, 2919 #endif 2920 { uoff(magic), "offsetof(struct user, magic)" }, 2921 { uoff(u_comm), "offsetof(struct user, u_comm)" }, 2922 #if defined(I386) || defined(X86_64) 2923 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" }, 2924 #endif /* I386 */ 2925 #endif /* !IA64 */ 2926 #endif /* !ALPHA */ 2927 #endif /* !POWERPC/!SPARC */ 2928 #endif /* LINUX */ 2929 #ifdef SUNOS4 2930 { uoff(u_pcb), "offsetof(struct user, u_pcb)" }, 2931 { uoff(u_procp), "offsetof(struct user, u_procp)" }, 2932 { uoff(u_ar0), "offsetof(struct user, u_ar0)" }, 2933 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" }, 2934 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" }, 2935 { uoff(u_ap), "offsetof(struct user, u_ap)" }, 2936 { uoff(u_qsave), "offsetof(struct user, u_qsave)" }, 2937 { uoff(u_rval1), "offsetof(struct user, u_rval1)" }, 2938 { uoff(u_rval2), "offsetof(struct user, u_rval2)" }, 2939 { uoff(u_error), "offsetof(struct user, u_error)" }, 2940 { uoff(u_eosys), "offsetof(struct user, u_eosys)" }, 2941 { uoff(u_ssave), "offsetof(struct user, u_ssave)" }, 2942 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" }, 2943 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" }, 2944 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" }, 2945 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" }, 2946 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" }, 2947 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" }, 2948 { uoff(u_code), "offsetof(struct user, u_code)" }, 2949 { uoff(u_addr), "offsetof(struct user, u_addr)" }, 2950 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" }, 2951 { uoff(u_ofile), "offsetof(struct user, u_ofile)" }, 2952 { uoff(u_pofile), "offsetof(struct user, u_pofile)" }, 2953 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" }, 2954 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"}, 2955 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" }, 2956 { uoff(u_cwd), "offsetof(struct user, u_cwd)" }, 2957 { uoff(u_cdir), "offsetof(struct user, u_cdir)" }, 2958 { uoff(u_rdir), "offsetof(struct user, u_rdir)" }, 2959 { uoff(u_cmask), "offsetof(struct user, u_cmask)" }, 2960 { uoff(u_ru), "offsetof(struct user, u_ru)" }, 2961 { uoff(u_cru), "offsetof(struct user, u_cru)" }, 2962 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" }, 2963 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" }, 2964 { uoff(u_ioch), "offsetof(struct user, u_ioch)" }, 2965 { uoff(u_start), "offsetof(struct user, u_start)" }, 2966 { uoff(u_acflag), "offsetof(struct user, u_acflag)" }, 2967 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" }, 2968 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" }, 2969 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" }, 2970 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"}, 2971 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" }, 2972 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" }, 2973 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"}, 2974 { uoff(u_lofault), "offsetof(struct user, u_lofault)" }, 2975 #endif /* SUNOS4 */ 2976 #ifndef HPPA 2977 { sizeof(struct user), "sizeof(struct user)" }, 2978 #endif 2979 { 0, NULL }, 2980 }; 2981 #endif 2982 2983 int 2984 sys_ptrace(tcp) 2985 struct tcb *tcp; 2986 { 2987 const struct xlat *x; 2988 long addr; 2989 2990 if (entering(tcp)) { 2991 printxval(ptrace_cmds, tcp->u_arg[0], 2992 #ifndef FREEBSD 2993 "PTRACE_???" 2994 #else 2995 "PT_???" 2996 #endif 2997 ); 2998 tprintf(", %lu, ", tcp->u_arg[1]); 2999 addr = tcp->u_arg[2]; 3000 #ifndef FREEBSD 3001 if (tcp->u_arg[0] == PTRACE_PEEKUSER 3002 || tcp->u_arg[0] == PTRACE_POKEUSER) { 3003 for (x = struct_user_offsets; x->str; x++) { 3004 if (x->val >= addr) 3005 break; 3006 } 3007 if (!x->str) 3008 tprintf("%#lx, ", addr); 3009 else if (x->val > addr && x != struct_user_offsets) { 3010 x--; 3011 tprintf("%s + %ld, ", x->str, addr - x->val); 3012 } 3013 else 3014 tprintf("%s, ", x->str); 3015 } 3016 else 3017 #endif 3018 tprintf("%#lx, ", tcp->u_arg[2]); 3019 #ifdef LINUX 3020 switch (tcp->u_arg[0]) { 3021 case PTRACE_PEEKDATA: 3022 case PTRACE_PEEKTEXT: 3023 case PTRACE_PEEKUSER: 3024 break; 3025 case PTRACE_CONT: 3026 case PTRACE_SINGLESTEP: 3027 case PTRACE_SYSCALL: 3028 case PTRACE_DETACH: 3029 printsignal(tcp->u_arg[3]); 3030 break; 3031 default: 3032 tprintf("%#lx", tcp->u_arg[3]); 3033 break; 3034 } 3035 } else { 3036 switch (tcp->u_arg[0]) { 3037 case PTRACE_PEEKDATA: 3038 case PTRACE_PEEKTEXT: 3039 case PTRACE_PEEKUSER: 3040 printnum(tcp, tcp->u_arg[3], "%#lx"); 3041 break; 3042 } 3043 } 3044 #endif /* LINUX */ 3045 #ifdef SUNOS4 3046 if (tcp->u_arg[0] == PTRACE_WRITEDATA || 3047 tcp->u_arg[0] == PTRACE_WRITETEXT) { 3048 tprintf("%lu, ", tcp->u_arg[3]); 3049 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]); 3050 } else if (tcp->u_arg[0] != PTRACE_READDATA && 3051 tcp->u_arg[0] != PTRACE_READTEXT) { 3052 tprintf("%#lx", tcp->u_arg[3]); 3053 } 3054 } else { 3055 if (tcp->u_arg[0] == PTRACE_READDATA || 3056 tcp->u_arg[0] == PTRACE_READTEXT) { 3057 tprintf("%lu, ", tcp->u_arg[3]); 3058 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]); 3059 } 3060 } 3061 #endif /* SUNOS4 */ 3062 #ifdef FREEBSD 3063 tprintf("%lu", tcp->u_arg[3]); 3064 } 3065 #endif /* FREEBSD */ 3066 return 0; 3067 } 3068 3069 #endif /* !SVR4 */ 3070 3071 #ifdef LINUX 3072 static const struct xlat futexops[] = { 3073 { FUTEX_WAIT, "FUTEX_WAIT" }, 3074 { FUTEX_WAKE, "FUTEX_WAKE" }, 3075 { FUTEX_FD, "FUTEX_FD" }, 3076 { FUTEX_REQUEUE,"FUTEX_REQUEUE" }, 3077 { 0, NULL } 3078 }; 3079 3080 int 3081 sys_futex(tcp) 3082 struct tcb *tcp; 3083 { 3084 if (entering(tcp)) { 3085 tprintf("%p, ", (void *) tcp->u_arg[0]); 3086 printxval(futexops, tcp->u_arg[1], "FUTEX_???"); 3087 tprintf(", %ld", tcp->u_arg[2]); 3088 if (tcp->u_arg[1] == FUTEX_WAIT) { 3089 tprintf(", "); 3090 printtv(tcp, tcp->u_arg[3]); 3091 } else if (tcp->u_arg[1] == FUTEX_REQUEUE) 3092 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]); 3093 } 3094 return 0; 3095 } 3096 3097 static void 3098 print_affinitylist(tcp, list, len) 3099 struct tcb *tcp; 3100 long list; 3101 unsigned int len; 3102 { 3103 int first = 1; 3104 tprintf(" {"); 3105 while (len >= sizeof (unsigned long)) { 3106 unsigned long w; 3107 umove(tcp, list, &w); 3108 tprintf("%s %lx", first ? "" : ",", w); 3109 first = 0; 3110 len -= sizeof (unsigned long); 3111 list += sizeof(unsigned long); 3112 } 3113 tprintf(" }"); 3114 } 3115 3116 int 3117 sys_sched_setaffinity(tcp) 3118 struct tcb *tcp; 3119 { 3120 if (entering(tcp)) { 3121 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); 3122 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]); 3123 } 3124 return 0; 3125 } 3126 3127 int 3128 sys_sched_getaffinity(tcp) 3129 struct tcb *tcp; 3130 { 3131 if (entering(tcp)) { 3132 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); 3133 } else { 3134 if (tcp->u_rval == -1) 3135 tprintf("%#lx", tcp->u_arg[2]); 3136 else 3137 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval); 3138 } 3139 return 0; 3140 } 3141 3142 static const struct xlat schedulers[] = { 3143 { SCHED_OTHER, "SCHED_OTHER" }, 3144 { SCHED_RR, "SCHED_RR" }, 3145 { SCHED_FIFO, "SCHED_FIFO" }, 3146 { 0, NULL } 3147 }; 3148 3149 int 3150 sys_sched_getscheduler(tcp) 3151 struct tcb *tcp; 3152 { 3153 if (entering(tcp)) { 3154 tprintf("%d", (int) tcp->u_arg[0]); 3155 } else if (! syserror(tcp)) { 3156 tcp->auxstr = xlookup (schedulers, tcp->u_rval); 3157 if (tcp->auxstr != NULL) 3158 return RVAL_STR; 3159 } 3160 return 0; 3161 } 3162 3163 int 3164 sys_sched_setscheduler(tcp) 3165 struct tcb *tcp; 3166 { 3167 if (entering(tcp)) { 3168 struct sched_param p; 3169 tprintf("%d, ", (int) tcp->u_arg[0]); 3170 printxval(schedulers, tcp->u_arg[1], "SCHED_???"); 3171 if (umove(tcp, tcp->u_arg[2], &p) < 0) 3172 tprintf(", %#lx", tcp->u_arg[2]); 3173 else 3174 tprintf(", { %d }", p.__sched_priority); 3175 } 3176 return 0; 3177 } 3178 3179 int 3180 sys_sched_getparam(tcp) 3181 struct tcb *tcp; 3182 { 3183 if (entering(tcp)) { 3184 tprintf("%d, ", (int) tcp->u_arg[0]); 3185 } else { 3186 struct sched_param p; 3187 if (umove(tcp, tcp->u_arg[1], &p) < 0) 3188 tprintf("%#lx", tcp->u_arg[1]); 3189 else 3190 tprintf("{ %d }", p.__sched_priority); 3191 } 3192 return 0; 3193 } 3194 3195 int 3196 sys_sched_setparam(tcp) 3197 struct tcb *tcp; 3198 { 3199 if (entering(tcp)) { 3200 struct sched_param p; 3201 if (umove(tcp, tcp->u_arg[1], &p) < 0) 3202 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]); 3203 else 3204 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority); 3205 } 3206 return 0; 3207 } 3208 3209 int 3210 sys_sched_get_priority_min(tcp) 3211 struct tcb *tcp; 3212 { 3213 if (entering(tcp)) { 3214 printxval(schedulers, tcp->u_arg[0], "SCHED_???"); 3215 } 3216 return 0; 3217 } 3218 3219 #ifdef X86_64 3220 #include <asm/prctl.h> 3221 3222 static const struct xlat archvals[] = { 3223 { ARCH_SET_GS, "ARCH_SET_GS" }, 3224 { ARCH_SET_FS, "ARCH_SET_FS" }, 3225 { ARCH_GET_FS, "ARCH_GET_FS" }, 3226 { ARCH_GET_GS, "ARCH_GET_GS" }, 3227 { 0, NULL }, 3228 }; 3229 3230 int 3231 sys_arch_prctl(tcp) 3232 struct tcb *tcp; 3233 { 3234 if (entering(tcp)) { 3235 printxval(archvals, tcp->u_arg[0], "ARCH_???"); 3236 if (tcp->u_arg[0] == ARCH_SET_GS 3237 || tcp->u_arg[0] == ARCH_SET_FS) 3238 tprintf(", %#lx", tcp->u_arg[1]); 3239 } else { 3240 if (tcp->u_arg[0] == ARCH_GET_GS 3241 || tcp->u_arg[0] == ARCH_GET_FS) { 3242 long int v; 3243 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1) 3244 tprintf(", [%#lx]", v); 3245 else 3246 tprintf(", %#lx", tcp->u_arg[1]); 3247 } 3248 } 3249 return 0; 3250 } 3251 #endif 3252 3253 #endif 3254