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