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