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