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