]> granicus.if.org Git - strace/blob - clone.c
eventfd: print first argument as unsigned int
[strace] / clone.c
1 #include "defs.h"
2
3 #include <sched.h>
4
5 #ifndef CSIGNAL
6 # define CSIGNAL 0x000000ff
7 #endif
8
9 #include "xlat/clone_flags.h"
10
11 #if defined IA64
12 # define ARG_FLAGS      0
13 # define ARG_STACK      1
14 # define ARG_STACKSIZE  (tcp->scno == SYS_clone2 ? 2 : -1)
15 # define ARG_PTID       (tcp->scno == SYS_clone2 ? 3 : 2)
16 # define ARG_CTID       (tcp->scno == SYS_clone2 ? 4 : 3)
17 # define ARG_TLS        (tcp->scno == SYS_clone2 ? 5 : 4)
18 #elif defined S390 || defined S390X || defined CRISV10 || defined CRISV32
19 # define ARG_STACK      0
20 # define ARG_FLAGS      1
21 # define ARG_PTID       2
22 # define ARG_CTID       3
23 # define ARG_TLS        4
24 #elif defined X86_64 || defined X32
25 /* x86 personality processes have the last two arguments flipped. */
26 # define ARG_FLAGS      0
27 # define ARG_STACK      1
28 # define ARG_PTID       2
29 # define ARG_CTID       ((current_personality != 1) ? 3 : 4)
30 # define ARG_TLS        ((current_personality != 1) ? 4 : 3)
31 #elif defined ALPHA || defined TILE || defined OR1K
32 # define ARG_FLAGS      0
33 # define ARG_STACK      1
34 # define ARG_PTID       2
35 # define ARG_CTID       3
36 # define ARG_TLS        4
37 #else
38 # define ARG_FLAGS      0
39 # define ARG_STACK      1
40 # define ARG_PTID       2
41 # define ARG_TLS        3
42 # define ARG_CTID       4
43 #endif
44
45 #if defined I386 || defined X86_64 || defined X32
46 extern void print_user_desc(struct tcb *, long);
47 #endif /* I386 || X86_64 || X32 */
48
49 SYS_FUNC(clone)
50 {
51         if (exiting(tcp)) {
52                 const char *sep = "|";
53                 unsigned long flags = tcp->u_arg[ARG_FLAGS];
54                 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
55 #ifdef ARG_STACKSIZE
56                 if (ARG_STACKSIZE != -1)
57                         tprintf("stack_size=%#lx, ",
58                                 tcp->u_arg[ARG_STACKSIZE]);
59 #endif
60                 tprints("flags=");
61                 if (!printflags(clone_flags, flags &~ CSIGNAL, NULL))
62                         sep = "";
63                 if ((flags & CSIGNAL) != 0)
64                         tprintf("%s%s", sep, signame(flags & CSIGNAL));
65                 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
66                               |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
67                         return 0;
68                 if (flags & CLONE_PARENT_SETTID)
69                         tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
70                 if (flags & CLONE_SETTLS) {
71 #if defined I386 || defined X86_64 || defined X32
72 # ifndef I386
73                         if (current_personality == 1)
74 # endif
75                         {
76                                 tprints(", tls=");
77                                 print_user_desc(tcp, tcp->u_arg[ARG_TLS]);
78                         }
79 # ifndef I386
80                         else
81 # endif
82 #endif /* I386 || X86_64 || X32 */
83                                 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
84                 }
85                 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
86                         tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
87         }
88         /* TODO on syscall entry:
89          * We can clear CLONE_PTRACE here since it is an ancient hack
90          * to allow us to catch children, and we use another hack for that.
91          * But CLONE_PTRACE can conceivably be used by malicious programs
92          * to subvert us. By clearing this bit, we can defend against it:
93          * in untraced execution, CLONE_PTRACE should have no effect.
94          *
95          * We can also clear CLONE_UNTRACED, since it allows to start
96          * children outside of our control. At the moment
97          * I'm trying to figure out whether there is a *legitimate*
98          * use of this flag which we should respect.
99          */
100         return 0;
101 }
102
103 SYS_FUNC(setns)
104 {
105         printfd(tcp, tcp->u_arg[0]);
106         tprints(", ");
107         printflags(clone_flags, tcp->u_arg[1], "CLONE_???");
108
109         return RVAL_DECODED;
110 }
111
112 SYS_FUNC(unshare)
113 {
114         printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
115         return RVAL_DECODED;
116 }
117
118 SYS_FUNC(fork)
119 {
120         return RVAL_DECODED | RVAL_UDECIMAL;
121 }