perf trace: Initial beautifier for ioctl's 'cmd' arg
[firefly-linux-kernel-4.4.55.git] / tools / perf / builtin-trace.c
1 #include <traceevent/event-parse.h>
2 #include "builtin.h"
3 #include "util/color.h"
4 #include "util/debug.h"
5 #include "util/evlist.h"
6 #include "util/machine.h"
7 #include "util/session.h"
8 #include "util/thread.h"
9 #include "util/parse-options.h"
10 #include "util/strlist.h"
11 #include "util/intlist.h"
12 #include "util/thread_map.h"
13
14 #include <libaudit.h>
15 #include <stdlib.h>
16 #include <sys/eventfd.h>
17 #include <sys/mman.h>
18 #include <linux/futex.h>
19
20 /* For older distros: */
21 #ifndef MAP_STACK
22 # define MAP_STACK              0x20000
23 #endif
24
25 #ifndef MADV_HWPOISON
26 # define MADV_HWPOISON          100
27 #endif
28
29 #ifndef MADV_MERGEABLE
30 # define MADV_MERGEABLE         12
31 #endif
32
33 #ifndef MADV_UNMERGEABLE
34 # define MADV_UNMERGEABLE       13
35 #endif
36
37 struct syscall_arg {
38         unsigned long val;
39         struct thread *thread;
40         struct trace  *trace;
41         void          *parm;
42         u8            idx;
43         u8            mask;
44 };
45
46 struct strarray {
47         int         offset;
48         int         nr_entries;
49         const char **entries;
50 };
51
52 #define DEFINE_STRARRAY(array) struct strarray strarray__##array = { \
53         .nr_entries = ARRAY_SIZE(array), \
54         .entries = array, \
55 }
56
57 #define DEFINE_STRARRAY_OFFSET(array, off) struct strarray strarray__##array = { \
58         .offset     = off, \
59         .nr_entries = ARRAY_SIZE(array), \
60         .entries = array, \
61 }
62
63 static size_t __syscall_arg__scnprintf_strarray(char *bf, size_t size,
64                                                 const char *intfmt,
65                                                 struct syscall_arg *arg)
66 {
67         struct strarray *sa = arg->parm;
68         int idx = arg->val - sa->offset;
69
70         if (idx < 0 || idx >= sa->nr_entries)
71                 return scnprintf(bf, size, intfmt, arg->val);
72
73         return scnprintf(bf, size, "%s", sa->entries[idx]);
74 }
75
76 static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size,
77                                               struct syscall_arg *arg)
78 {
79         return __syscall_arg__scnprintf_strarray(bf, size, "%d", arg);
80 }
81
82 #define SCA_STRARRAY syscall_arg__scnprintf_strarray
83
84 static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size,
85                                                  struct syscall_arg *arg)
86 {
87         return __syscall_arg__scnprintf_strarray(bf, size, "%#x", arg);
88 }
89
90 #define SCA_STRHEXARRAY syscall_arg__scnprintf_strhexarray
91
92 static size_t syscall_arg__scnprintf_fd(char *bf, size_t size,
93                                         struct syscall_arg *arg);
94
95 #define SCA_FD syscall_arg__scnprintf_fd
96
97 static size_t syscall_arg__scnprintf_fd_at(char *bf, size_t size,
98                                            struct syscall_arg *arg)
99 {
100         int fd = arg->val;
101
102         if (fd == AT_FDCWD)
103                 return scnprintf(bf, size, "CWD");
104
105         return syscall_arg__scnprintf_fd(bf, size, arg);
106 }
107
108 #define SCA_FDAT syscall_arg__scnprintf_fd_at
109
110 static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size,
111                                               struct syscall_arg *arg);
112
113 #define SCA_CLOSE_FD syscall_arg__scnprintf_close_fd
114
115 static size_t syscall_arg__scnprintf_hex(char *bf, size_t size,
116                                          struct syscall_arg *arg)
117 {
118         return scnprintf(bf, size, "%#lx", arg->val);
119 }
120
121 #define SCA_HEX syscall_arg__scnprintf_hex
122
123 static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
124                                                struct syscall_arg *arg)
125 {
126         int printed = 0, prot = arg->val;
127
128         if (prot == PROT_NONE)
129                 return scnprintf(bf, size, "NONE");
130 #define P_MMAP_PROT(n) \
131         if (prot & PROT_##n) { \
132                 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
133                 prot &= ~PROT_##n; \
134         }
135
136         P_MMAP_PROT(EXEC);
137         P_MMAP_PROT(READ);
138         P_MMAP_PROT(WRITE);
139 #ifdef PROT_SEM
140         P_MMAP_PROT(SEM);
141 #endif
142         P_MMAP_PROT(GROWSDOWN);
143         P_MMAP_PROT(GROWSUP);
144 #undef P_MMAP_PROT
145
146         if (prot)
147                 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", prot);
148
149         return printed;
150 }
151
152 #define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot
153
154 static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
155                                                 struct syscall_arg *arg)
156 {
157         int printed = 0, flags = arg->val;
158
159 #define P_MMAP_FLAG(n) \
160         if (flags & MAP_##n) { \
161                 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
162                 flags &= ~MAP_##n; \
163         }
164
165         P_MMAP_FLAG(SHARED);
166         P_MMAP_FLAG(PRIVATE);
167 #ifdef MAP_32BIT
168         P_MMAP_FLAG(32BIT);
169 #endif
170         P_MMAP_FLAG(ANONYMOUS);
171         P_MMAP_FLAG(DENYWRITE);
172         P_MMAP_FLAG(EXECUTABLE);
173         P_MMAP_FLAG(FILE);
174         P_MMAP_FLAG(FIXED);
175         P_MMAP_FLAG(GROWSDOWN);
176 #ifdef MAP_HUGETLB
177         P_MMAP_FLAG(HUGETLB);
178 #endif
179         P_MMAP_FLAG(LOCKED);
180         P_MMAP_FLAG(NONBLOCK);
181         P_MMAP_FLAG(NORESERVE);
182         P_MMAP_FLAG(POPULATE);
183         P_MMAP_FLAG(STACK);
184 #ifdef MAP_UNINITIALIZED
185         P_MMAP_FLAG(UNINITIALIZED);
186 #endif
187 #undef P_MMAP_FLAG
188
189         if (flags)
190                 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
191
192         return printed;
193 }
194
195 #define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags
196
197 static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
198                                                       struct syscall_arg *arg)
199 {
200         int behavior = arg->val;
201
202         switch (behavior) {
203 #define P_MADV_BHV(n) case MADV_##n: return scnprintf(bf, size, #n)
204         P_MADV_BHV(NORMAL);
205         P_MADV_BHV(RANDOM);
206         P_MADV_BHV(SEQUENTIAL);
207         P_MADV_BHV(WILLNEED);
208         P_MADV_BHV(DONTNEED);
209         P_MADV_BHV(REMOVE);
210         P_MADV_BHV(DONTFORK);
211         P_MADV_BHV(DOFORK);
212         P_MADV_BHV(HWPOISON);
213 #ifdef MADV_SOFT_OFFLINE
214         P_MADV_BHV(SOFT_OFFLINE);
215 #endif
216         P_MADV_BHV(MERGEABLE);
217         P_MADV_BHV(UNMERGEABLE);
218 #ifdef MADV_HUGEPAGE
219         P_MADV_BHV(HUGEPAGE);
220 #endif
221 #ifdef MADV_NOHUGEPAGE
222         P_MADV_BHV(NOHUGEPAGE);
223 #endif
224 #ifdef MADV_DONTDUMP
225         P_MADV_BHV(DONTDUMP);
226 #endif
227 #ifdef MADV_DODUMP
228         P_MADV_BHV(DODUMP);
229 #endif
230 #undef P_MADV_PHV
231         default: break;
232         }
233
234         return scnprintf(bf, size, "%#x", behavior);
235 }
236
237 #define SCA_MADV_BHV syscall_arg__scnprintf_madvise_behavior
238
239 static size_t syscall_arg__scnprintf_flock(char *bf, size_t size,
240                                            struct syscall_arg *arg)
241 {
242         int printed = 0, op = arg->val;
243
244         if (op == 0)
245                 return scnprintf(bf, size, "NONE");
246 #define P_CMD(cmd) \
247         if ((op & LOCK_##cmd) == LOCK_##cmd) { \
248                 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #cmd); \
249                 op &= ~LOCK_##cmd; \
250         }
251
252         P_CMD(SH);
253         P_CMD(EX);
254         P_CMD(NB);
255         P_CMD(UN);
256         P_CMD(MAND);
257         P_CMD(RW);
258         P_CMD(READ);
259         P_CMD(WRITE);
260 #undef P_OP
261
262         if (op)
263                 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", op);
264
265         return printed;
266 }
267
268 #define SCA_FLOCK syscall_arg__scnprintf_flock
269
270 static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct syscall_arg *arg)
271 {
272         enum syscall_futex_args {
273                 SCF_UADDR   = (1 << 0),
274                 SCF_OP      = (1 << 1),
275                 SCF_VAL     = (1 << 2),
276                 SCF_TIMEOUT = (1 << 3),
277                 SCF_UADDR2  = (1 << 4),
278                 SCF_VAL3    = (1 << 5),
279         };
280         int op = arg->val;
281         int cmd = op & FUTEX_CMD_MASK;
282         size_t printed = 0;
283
284         switch (cmd) {
285 #define P_FUTEX_OP(n) case FUTEX_##n: printed = scnprintf(bf, size, #n);
286         P_FUTEX_OP(WAIT);           arg->mask |= SCF_VAL3|SCF_UADDR2;             break;
287         P_FUTEX_OP(WAKE);           arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
288         P_FUTEX_OP(FD);             arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
289         P_FUTEX_OP(REQUEUE);        arg->mask |= SCF_VAL3|SCF_TIMEOUT;            break;
290         P_FUTEX_OP(CMP_REQUEUE);    arg->mask |= SCF_TIMEOUT;                     break;
291         P_FUTEX_OP(CMP_REQUEUE_PI); arg->mask |= SCF_TIMEOUT;                     break;
292         P_FUTEX_OP(WAKE_OP);                                                      break;
293         P_FUTEX_OP(LOCK_PI);        arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
294         P_FUTEX_OP(UNLOCK_PI);      arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
295         P_FUTEX_OP(TRYLOCK_PI);     arg->mask |= SCF_VAL3|SCF_UADDR2;             break;
296         P_FUTEX_OP(WAIT_BITSET);    arg->mask |= SCF_UADDR2;                      break;
297         P_FUTEX_OP(WAKE_BITSET);    arg->mask |= SCF_UADDR2;                      break;
298         P_FUTEX_OP(WAIT_REQUEUE_PI);                                              break;
299         default: printed = scnprintf(bf, size, "%#x", cmd);                       break;
300         }
301
302         if (op & FUTEX_PRIVATE_FLAG)
303                 printed += scnprintf(bf + printed, size - printed, "|PRIV");
304
305         if (op & FUTEX_CLOCK_REALTIME)
306                 printed += scnprintf(bf + printed, size - printed, "|CLKRT");
307
308         return printed;
309 }
310
311 #define SCA_FUTEX_OP  syscall_arg__scnprintf_futex_op
312
313 static const char *epoll_ctl_ops[] = { "ADD", "DEL", "MOD", };
314 static DEFINE_STRARRAY_OFFSET(epoll_ctl_ops, 1);
315
316 static const char *itimers[] = { "REAL", "VIRTUAL", "PROF", };
317 static DEFINE_STRARRAY(itimers);
318
319 static const char *whences[] = { "SET", "CUR", "END",
320 #ifdef SEEK_DATA
321 "DATA",
322 #endif
323 #ifdef SEEK_HOLE
324 "HOLE",
325 #endif
326 };
327 static DEFINE_STRARRAY(whences);
328
329 static const char *fcntl_cmds[] = {
330         "DUPFD", "GETFD", "SETFD", "GETFL", "SETFL", "GETLK", "SETLK",
331         "SETLKW", "SETOWN", "GETOWN", "SETSIG", "GETSIG", "F_GETLK64",
332         "F_SETLK64", "F_SETLKW64", "F_SETOWN_EX", "F_GETOWN_EX",
333         "F_GETOWNER_UIDS",
334 };
335 static DEFINE_STRARRAY(fcntl_cmds);
336
337 static const char *rlimit_resources[] = {
338         "CPU", "FSIZE", "DATA", "STACK", "CORE", "RSS", "NPROC", "NOFILE",
339         "MEMLOCK", "AS", "LOCKS", "SIGPENDING", "MSGQUEUE", "NICE", "RTPRIO",
340         "RTTIME",
341 };
342 static DEFINE_STRARRAY(rlimit_resources);
343
344 static const char *sighow[] = { "BLOCK", "UNBLOCK", "SETMASK", };
345 static DEFINE_STRARRAY(sighow);
346
347 static const char *clockid[] = {
348         "REALTIME", "MONOTONIC", "PROCESS_CPUTIME_ID", "THREAD_CPUTIME_ID",
349         "MONOTONIC_RAW", "REALTIME_COARSE", "MONOTONIC_COARSE",
350 };
351 static DEFINE_STRARRAY(clockid);
352
353 static const char *socket_families[] = {
354         "UNSPEC", "LOCAL", "INET", "AX25", "IPX", "APPLETALK", "NETROM",
355         "BRIDGE", "ATMPVC", "X25", "INET6", "ROSE", "DECnet", "NETBEUI",
356         "SECURITY", "KEY", "NETLINK", "PACKET", "ASH", "ECONET", "ATMSVC",
357         "RDS", "SNA", "IRDA", "PPPOX", "WANPIPE", "LLC", "IB", "CAN", "TIPC",
358         "BLUETOOTH", "IUCV", "RXRPC", "ISDN", "PHONET", "IEEE802154", "CAIF",
359         "ALG", "NFC", "VSOCK",
360 };
361 static DEFINE_STRARRAY(socket_families);
362
363 #ifndef SOCK_TYPE_MASK
364 #define SOCK_TYPE_MASK 0xf
365 #endif
366
367 static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size,
368                                                       struct syscall_arg *arg)
369 {
370         size_t printed;
371         int type = arg->val,
372             flags = type & ~SOCK_TYPE_MASK;
373
374         type &= SOCK_TYPE_MASK;
375         /*
376          * Can't use a strarray, MIPS may override for ABI reasons.
377          */
378         switch (type) {
379 #define P_SK_TYPE(n) case SOCK_##n: printed = scnprintf(bf, size, #n); break;
380         P_SK_TYPE(STREAM);
381         P_SK_TYPE(DGRAM);
382         P_SK_TYPE(RAW);
383         P_SK_TYPE(RDM);
384         P_SK_TYPE(SEQPACKET);
385         P_SK_TYPE(DCCP);
386         P_SK_TYPE(PACKET);
387 #undef P_SK_TYPE
388         default:
389                 printed = scnprintf(bf, size, "%#x", type);
390         }
391
392 #define P_SK_FLAG(n) \
393         if (flags & SOCK_##n) { \
394                 printed += scnprintf(bf + printed, size - printed, "|%s", #n); \
395                 flags &= ~SOCK_##n; \
396         }
397
398         P_SK_FLAG(CLOEXEC);
399         P_SK_FLAG(NONBLOCK);
400 #undef P_SK_FLAG
401
402         if (flags)
403                 printed += scnprintf(bf + printed, size - printed, "|%#x", flags);
404
405         return printed;
406 }
407
408 #define SCA_SK_TYPE syscall_arg__scnprintf_socket_type
409
410 #ifndef MSG_PROBE
411 #define MSG_PROBE            0x10
412 #endif
413 #ifndef MSG_WAITFORONE
414 #define MSG_WAITFORONE  0x10000
415 #endif
416 #ifndef MSG_SENDPAGE_NOTLAST
417 #define MSG_SENDPAGE_NOTLAST 0x20000
418 #endif
419 #ifndef MSG_FASTOPEN
420 #define MSG_FASTOPEN         0x20000000
421 #endif
422
423 static size_t syscall_arg__scnprintf_msg_flags(char *bf, size_t size,
424                                                struct syscall_arg *arg)
425 {
426         int printed = 0, flags = arg->val;
427
428         if (flags == 0)
429                 return scnprintf(bf, size, "NONE");
430 #define P_MSG_FLAG(n) \
431         if (flags & MSG_##n) { \
432                 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
433                 flags &= ~MSG_##n; \
434         }
435
436         P_MSG_FLAG(OOB);
437         P_MSG_FLAG(PEEK);
438         P_MSG_FLAG(DONTROUTE);
439         P_MSG_FLAG(TRYHARD);
440         P_MSG_FLAG(CTRUNC);
441         P_MSG_FLAG(PROBE);
442         P_MSG_FLAG(TRUNC);
443         P_MSG_FLAG(DONTWAIT);
444         P_MSG_FLAG(EOR);
445         P_MSG_FLAG(WAITALL);
446         P_MSG_FLAG(FIN);
447         P_MSG_FLAG(SYN);
448         P_MSG_FLAG(CONFIRM);
449         P_MSG_FLAG(RST);
450         P_MSG_FLAG(ERRQUEUE);
451         P_MSG_FLAG(NOSIGNAL);
452         P_MSG_FLAG(MORE);
453         P_MSG_FLAG(WAITFORONE);
454         P_MSG_FLAG(SENDPAGE_NOTLAST);
455         P_MSG_FLAG(FASTOPEN);
456         P_MSG_FLAG(CMSG_CLOEXEC);
457 #undef P_MSG_FLAG
458
459         if (flags)
460                 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
461
462         return printed;
463 }
464
465 #define SCA_MSG_FLAGS syscall_arg__scnprintf_msg_flags
466
467 static size_t syscall_arg__scnprintf_access_mode(char *bf, size_t size,
468                                                  struct syscall_arg *arg)
469 {
470         size_t printed = 0;
471         int mode = arg->val;
472
473         if (mode == F_OK) /* 0 */
474                 return scnprintf(bf, size, "F");
475 #define P_MODE(n) \
476         if (mode & n##_OK) { \
477                 printed += scnprintf(bf + printed, size - printed, "%s", #n); \
478                 mode &= ~n##_OK; \
479         }
480
481         P_MODE(R);
482         P_MODE(W);
483         P_MODE(X);
484 #undef P_MODE
485
486         if (mode)
487                 printed += scnprintf(bf + printed, size - printed, "|%#x", mode);
488
489         return printed;
490 }
491
492 #define SCA_ACCMODE syscall_arg__scnprintf_access_mode
493
494 static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size,
495                                                struct syscall_arg *arg)
496 {
497         int printed = 0, flags = arg->val;
498
499         if (!(flags & O_CREAT))
500                 arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */
501
502         if (flags == 0)
503                 return scnprintf(bf, size, "RDONLY");
504 #define P_FLAG(n) \
505         if (flags & O_##n) { \
506                 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
507                 flags &= ~O_##n; \
508         }
509
510         P_FLAG(APPEND);
511         P_FLAG(ASYNC);
512         P_FLAG(CLOEXEC);
513         P_FLAG(CREAT);
514         P_FLAG(DIRECT);
515         P_FLAG(DIRECTORY);
516         P_FLAG(EXCL);
517         P_FLAG(LARGEFILE);
518         P_FLAG(NOATIME);
519         P_FLAG(NOCTTY);
520 #ifdef O_NONBLOCK
521         P_FLAG(NONBLOCK);
522 #elif O_NDELAY
523         P_FLAG(NDELAY);
524 #endif
525 #ifdef O_PATH
526         P_FLAG(PATH);
527 #endif
528         P_FLAG(RDWR);
529 #ifdef O_DSYNC
530         if ((flags & O_SYNC) == O_SYNC)
531                 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", "SYNC");
532         else {
533                 P_FLAG(DSYNC);
534         }
535 #else
536         P_FLAG(SYNC);
537 #endif
538         P_FLAG(TRUNC);
539         P_FLAG(WRONLY);
540 #undef P_FLAG
541
542         if (flags)
543                 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
544
545         return printed;
546 }
547
548 #define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags
549
550 static size_t syscall_arg__scnprintf_eventfd_flags(char *bf, size_t size,
551                                                    struct syscall_arg *arg)
552 {
553         int printed = 0, flags = arg->val;
554
555         if (flags == 0)
556                 return scnprintf(bf, size, "NONE");
557 #define P_FLAG(n) \
558         if (flags & EFD_##n) { \
559                 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
560                 flags &= ~EFD_##n; \
561         }
562
563         P_FLAG(SEMAPHORE);
564         P_FLAG(CLOEXEC);
565         P_FLAG(NONBLOCK);
566 #undef P_FLAG
567
568         if (flags)
569                 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
570
571         return printed;
572 }
573
574 #define SCA_EFD_FLAGS syscall_arg__scnprintf_eventfd_flags
575
576 static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size,
577                                                 struct syscall_arg *arg)
578 {
579         int printed = 0, flags = arg->val;
580
581 #define P_FLAG(n) \
582         if (flags & O_##n) { \
583                 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
584                 flags &= ~O_##n; \
585         }
586
587         P_FLAG(CLOEXEC);
588         P_FLAG(NONBLOCK);
589 #undef P_FLAG
590
591         if (flags)
592                 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
593
594         return printed;
595 }
596
597 #define SCA_PIPE_FLAGS syscall_arg__scnprintf_pipe_flags
598
599 static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg)
600 {
601         int sig = arg->val;
602
603         switch (sig) {
604 #define P_SIGNUM(n) case SIG##n: return scnprintf(bf, size, #n)
605         P_SIGNUM(HUP);
606         P_SIGNUM(INT);
607         P_SIGNUM(QUIT);
608         P_SIGNUM(ILL);
609         P_SIGNUM(TRAP);
610         P_SIGNUM(ABRT);
611         P_SIGNUM(BUS);
612         P_SIGNUM(FPE);
613         P_SIGNUM(KILL);
614         P_SIGNUM(USR1);
615         P_SIGNUM(SEGV);
616         P_SIGNUM(USR2);
617         P_SIGNUM(PIPE);
618         P_SIGNUM(ALRM);
619         P_SIGNUM(TERM);
620         P_SIGNUM(STKFLT);
621         P_SIGNUM(CHLD);
622         P_SIGNUM(CONT);
623         P_SIGNUM(STOP);
624         P_SIGNUM(TSTP);
625         P_SIGNUM(TTIN);
626         P_SIGNUM(TTOU);
627         P_SIGNUM(URG);
628         P_SIGNUM(XCPU);
629         P_SIGNUM(XFSZ);
630         P_SIGNUM(VTALRM);
631         P_SIGNUM(PROF);
632         P_SIGNUM(WINCH);
633         P_SIGNUM(IO);
634         P_SIGNUM(PWR);
635         P_SIGNUM(SYS);
636         default: break;
637         }
638
639         return scnprintf(bf, size, "%#x", sig);
640 }
641
642 #define SCA_SIGNUM syscall_arg__scnprintf_signum
643
644 #define TCGETS          0x5401
645
646 static const char *tioctls[] = {
647         "TCGETS", "TCSETS", "TCSETSW", "TCSETSF", "TCGETA", "TCSETA", "TCSETAW",
648         "TCSETAF", "TCSBRK", "TCXONC", "TCFLSH", "TIOCEXCL", "TIOCNXCL",
649         "TIOCSCTTY", "TIOCGPGRP", "TIOCSPGRP", "TIOCOUTQ", "TIOCSTI",
650         "TIOCGWINSZ", "TIOCSWINSZ", "TIOCMGET", "TIOCMBIS", "TIOCMBIC",
651         "TIOCMSET", "TIOCGSOFTCAR", "TIOCSSOFTCAR", "FIONREAD", "TIOCLINUX",
652         "TIOCCONS", "TIOCGSERIAL", "TIOCSSERIAL", "TIOCPKT", "FIONBIO",
653         "TIOCNOTTY", "TIOCSETD", "TIOCGETD", "TCSBRKP", [0x27] = "TIOCSBRK",
654         "TIOCCBRK", "TIOCGSID", "TCGETS2", "TCSETS2", "TCSETSW2", "TCSETSF2",
655         "TIOCGRS485", "TIOCSRS485", "TIOCGPTN", "TIOCSPTLCK",
656         "TIOCGDEV||TCGETX", "TCSETX", "TCSETXF", "TCSETXW", "TIOCSIG",
657         "TIOCVHANGUP", "TIOCGPKT", "TIOCGPTLCK", "TIOCGEXCL",
658         [0x50] = "FIONCLEX", "FIOCLEX", "FIOASYNC", "TIOCSERCONFIG",
659         "TIOCSERGWILD", "TIOCSERSWILD", "TIOCGLCKTRMIOS", "TIOCSLCKTRMIOS",
660         "TIOCSERGSTRUCT", "TIOCSERGETLSR", "TIOCSERGETMULTI", "TIOCSERSETMULTI",
661         "TIOCMIWAIT", "TIOCGICOUNT", [0x60] = "FIOQSIZE",
662 };
663
664 static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401);
665
666 #define STRARRAY(arg, name, array) \
667           .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \
668           .arg_parm      = { [arg] = &strarray__##array, }
669
670 static struct syscall_fmt {
671         const char *name;
672         const char *alias;
673         size_t     (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg);
674         void       *arg_parm[6];
675         bool       errmsg;
676         bool       timeout;
677         bool       hexret;
678 } syscall_fmts[] = {
679         { .name     = "access",     .errmsg = true,
680           .arg_scnprintf = { [1] = SCA_ACCMODE, /* mode */ }, },
681         { .name     = "arch_prctl", .errmsg = true, .alias = "prctl", },
682         { .name     = "brk",        .hexret = true,
683           .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, },
684         { .name     = "clock_gettime",  .errmsg = true, STRARRAY(0, clk_id, clockid), },
685         { .name     = "close",      .errmsg = true,
686           .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, }, 
687         { .name     = "connect",    .errmsg = true, },
688         { .name     = "dup",        .errmsg = true,
689           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
690         { .name     = "dup2",       .errmsg = true,
691           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
692         { .name     = "dup3",       .errmsg = true,
693           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
694         { .name     = "epoll_ctl",  .errmsg = true, STRARRAY(1, op, epoll_ctl_ops), },
695         { .name     = "eventfd2",   .errmsg = true,
696           .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, },
697         { .name     = "faccessat",  .errmsg = true,
698           .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
699         { .name     = "fadvise64",  .errmsg = true,
700           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
701         { .name     = "fallocate",  .errmsg = true,
702           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
703         { .name     = "fchdir",     .errmsg = true,
704           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
705         { .name     = "fchmod",     .errmsg = true,
706           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
707         { .name     = "fchmodat",   .errmsg = true,
708           .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
709         { .name     = "fchown",     .errmsg = true,
710           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
711         { .name     = "fchownat",   .errmsg = true,
712           .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
713         { .name     = "fcntl",      .errmsg = true,
714           .arg_scnprintf = { [0] = SCA_FD, /* fd */
715                              [1] = SCA_STRARRAY, /* cmd */ },
716           .arg_parm      = { [1] = &strarray__fcntl_cmds, /* cmd */ }, },
717         { .name     = "fdatasync",  .errmsg = true,
718           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
719         { .name     = "flock",      .errmsg = true,
720           .arg_scnprintf = { [0] = SCA_FD, /* fd */
721                              [1] = SCA_FLOCK, /* cmd */ }, },
722         { .name     = "fsetxattr",  .errmsg = true,
723           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
724         { .name     = "fstat",      .errmsg = true, .alias = "newfstat",
725           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
726         { .name     = "fstatat",    .errmsg = true, .alias = "newfstatat",
727           .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
728         { .name     = "fstatfs",    .errmsg = true,
729           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
730         { .name     = "fsync",    .errmsg = true,
731           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
732         { .name     = "ftruncate", .errmsg = true,
733           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
734         { .name     = "futex",      .errmsg = true,
735           .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, },
736         { .name     = "futimesat", .errmsg = true,
737           .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
738         { .name     = "getdents",   .errmsg = true,
739           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
740         { .name     = "getdents64", .errmsg = true,
741           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
742         { .name     = "getitimer",  .errmsg = true, STRARRAY(0, which, itimers), },
743         { .name     = "getrlimit",  .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
744         { .name     = "ioctl",      .errmsg = true,
745           .arg_scnprintf = { [0] = SCA_FD, /* fd */ 
746                              [1] = SCA_STRHEXARRAY, /* cmd */
747                              [2] = SCA_HEX, /* arg */ },
748           .arg_parm      = { [1] = &strarray__tioctls, /* cmd */ }, },
749         { .name     = "kill",       .errmsg = true,
750           .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
751         { .name     = "linkat",     .errmsg = true,
752           .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
753         { .name     = "lseek",      .errmsg = true,
754           .arg_scnprintf = { [0] = SCA_FD, /* fd */
755                              [2] = SCA_STRARRAY, /* whence */ },
756           .arg_parm      = { [2] = &strarray__whences, /* whence */ }, },
757         { .name     = "lstat",      .errmsg = true, .alias = "newlstat", },
758         { .name     = "madvise",    .errmsg = true,
759           .arg_scnprintf = { [0] = SCA_HEX,      /* start */
760                              [2] = SCA_MADV_BHV, /* behavior */ }, },
761         { .name     = "mkdirat",    .errmsg = true,
762           .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
763         { .name     = "mknodat",    .errmsg = true,
764           .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, 
765         { .name     = "mlock",      .errmsg = true,
766           .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
767         { .name     = "mlockall",   .errmsg = true,
768           .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
769         { .name     = "mmap",       .hexret = true,
770           .arg_scnprintf = { [0] = SCA_HEX,       /* addr */
771                              [2] = SCA_MMAP_PROT, /* prot */
772                              [3] = SCA_MMAP_FLAGS, /* flags */ }, },
773         { .name     = "mprotect",   .errmsg = true,
774           .arg_scnprintf = { [0] = SCA_HEX, /* start */
775                              [2] = SCA_MMAP_PROT, /* prot */ }, },
776         { .name     = "mremap",     .hexret = true,
777           .arg_scnprintf = { [0] = SCA_HEX, /* addr */
778                              [4] = SCA_HEX, /* new_addr */ }, },
779         { .name     = "munlock",    .errmsg = true,
780           .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
781         { .name     = "munmap",     .errmsg = true,
782           .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
783         { .name     = "name_to_handle_at", .errmsg = true,
784           .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
785         { .name     = "newfstatat", .errmsg = true,
786           .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
787         { .name     = "open",       .errmsg = true,
788           .arg_scnprintf = { [1] = SCA_OPEN_FLAGS, /* flags */ }, },
789         { .name     = "open_by_handle_at", .errmsg = true,
790           .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
791                              [2] = SCA_OPEN_FLAGS, /* flags */ }, },
792         { .name     = "openat",     .errmsg = true,
793           .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
794                              [2] = SCA_OPEN_FLAGS, /* flags */ }, },
795         { .name     = "pipe2",      .errmsg = true,
796           .arg_scnprintf = { [1] = SCA_PIPE_FLAGS, /* flags */ }, },
797         { .name     = "poll",       .errmsg = true, .timeout = true, },
798         { .name     = "ppoll",      .errmsg = true, .timeout = true, },
799         { .name     = "pread",      .errmsg = true, .alias = "pread64",
800           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
801         { .name     = "preadv",     .errmsg = true, .alias = "pread",
802           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
803         { .name     = "prlimit64",  .errmsg = true, STRARRAY(1, resource, rlimit_resources), },
804         { .name     = "pwrite",     .errmsg = true, .alias = "pwrite64",
805           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
806         { .name     = "pwritev",    .errmsg = true,
807           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
808         { .name     = "read",       .errmsg = true,
809           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
810         { .name     = "readlinkat", .errmsg = true,
811           .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
812         { .name     = "readv",      .errmsg = true,
813           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
814         { .name     = "recvfrom",   .errmsg = true,
815           .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
816         { .name     = "recvmmsg",   .errmsg = true,
817           .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
818         { .name     = "recvmsg",    .errmsg = true,
819           .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, },
820         { .name     = "renameat",   .errmsg = true,
821           .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
822         { .name     = "rt_sigaction", .errmsg = true,
823           .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, },
824         { .name     = "rt_sigprocmask",  .errmsg = true, STRARRAY(0, how, sighow), },
825         { .name     = "rt_sigqueueinfo", .errmsg = true,
826           .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
827         { .name     = "rt_tgsigqueueinfo", .errmsg = true,
828           .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, },
829         { .name     = "select",     .errmsg = true, .timeout = true, },
830         { .name     = "sendmmsg",    .errmsg = true,
831           .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
832         { .name     = "sendmsg",    .errmsg = true,
833           .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, },
834         { .name     = "sendto",     .errmsg = true,
835           .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, },
836         { .name     = "setitimer",  .errmsg = true, STRARRAY(0, which, itimers), },
837         { .name     = "setrlimit",  .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
838         { .name     = "shutdown",   .errmsg = true,
839           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
840         { .name     = "socket",     .errmsg = true,
841           .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */
842                              [1] = SCA_SK_TYPE, /* type */ },
843           .arg_parm      = { [0] = &strarray__socket_families, /* family */ }, },
844         { .name     = "socketpair", .errmsg = true,
845           .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */
846                              [1] = SCA_SK_TYPE, /* type */ },
847           .arg_parm      = { [0] = &strarray__socket_families, /* family */ }, },
848         { .name     = "stat",       .errmsg = true, .alias = "newstat", },
849         { .name     = "symlinkat",  .errmsg = true,
850           .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, 
851         { .name     = "tgkill",     .errmsg = true,
852           .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, },
853         { .name     = "tkill",      .errmsg = true,
854           .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
855         { .name     = "uname",      .errmsg = true, .alias = "newuname", },
856         { .name     = "unlinkat",   .errmsg = true,
857           .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
858         { .name     = "utimensat",  .errmsg = true,
859           .arg_scnprintf = { [0] = SCA_FDAT, /* dirfd */ }, },
860         { .name     = "write",      .errmsg = true,
861           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
862         { .name     = "writev",     .errmsg = true,
863           .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, 
864 };
865
866 static int syscall_fmt__cmp(const void *name, const void *fmtp)
867 {
868         const struct syscall_fmt *fmt = fmtp;
869         return strcmp(name, fmt->name);
870 }
871
872 static struct syscall_fmt *syscall_fmt__find(const char *name)
873 {
874         const int nmemb = ARRAY_SIZE(syscall_fmts);
875         return bsearch(name, syscall_fmts, nmemb, sizeof(struct syscall_fmt), syscall_fmt__cmp);
876 }
877
878 struct syscall {
879         struct event_format *tp_format;
880         const char          *name;
881         bool                filtered;
882         struct syscall_fmt  *fmt;
883         size_t              (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg);
884         void                **arg_parm;
885 };
886
887 static size_t fprintf_duration(unsigned long t, FILE *fp)
888 {
889         double duration = (double)t / NSEC_PER_MSEC;
890         size_t printed = fprintf(fp, "(");
891
892         if (duration >= 1.0)
893                 printed += color_fprintf(fp, PERF_COLOR_RED, "%6.3f ms", duration);
894         else if (duration >= 0.01)
895                 printed += color_fprintf(fp, PERF_COLOR_YELLOW, "%6.3f ms", duration);
896         else
897                 printed += color_fprintf(fp, PERF_COLOR_NORMAL, "%6.3f ms", duration);
898         return printed + fprintf(fp, "): ");
899 }
900
901 struct thread_trace {
902         u64               entry_time;
903         u64               exit_time;
904         bool              entry_pending;
905         unsigned long     nr_events;
906         char              *entry_str;
907         double            runtime_ms;
908         struct {
909                 int       max;
910                 char      **table;
911         } paths;
912 };
913
914 static struct thread_trace *thread_trace__new(void)
915 {
916         struct thread_trace *ttrace =  zalloc(sizeof(struct thread_trace));
917
918         if (ttrace)
919                 ttrace->paths.max = -1;
920
921         return ttrace;
922 }
923
924 static struct thread_trace *thread__trace(struct thread *thread, FILE *fp)
925 {
926         struct thread_trace *ttrace;
927
928         if (thread == NULL)
929                 goto fail;
930
931         if (thread->priv == NULL)
932                 thread->priv = thread_trace__new();
933                 
934         if (thread->priv == NULL)
935                 goto fail;
936
937         ttrace = thread->priv;
938         ++ttrace->nr_events;
939
940         return ttrace;
941 fail:
942         color_fprintf(fp, PERF_COLOR_RED,
943                       "WARNING: not enough memory, dropping samples!\n");
944         return NULL;
945 }
946
947 struct trace {
948         struct perf_tool        tool;
949         int                     audit_machine;
950         struct {
951                 int             max;
952                 struct syscall  *table;
953         } syscalls;
954         struct perf_record_opts opts;
955         struct machine          *host;
956         u64                     base_time;
957         bool                    full_time;
958         FILE                    *output;
959         unsigned long           nr_events;
960         struct strlist          *ev_qualifier;
961         bool                    not_ev_qualifier;
962         bool                    live;
963         struct intlist          *tid_list;
964         struct intlist          *pid_list;
965         bool                    sched;
966         bool                    multiple_threads;
967         bool                    show_comm;
968         double                  duration_filter;
969         double                  runtime_ms;
970 };
971
972 static int thread__read_fd_path(struct thread *thread, int fd)
973 {
974         struct thread_trace *ttrace = thread->priv;
975         char linkname[PATH_MAX], pathname[PATH_MAX];
976         struct stat st;
977         int ret;
978
979         if (thread->pid_ == thread->tid) {
980                 scnprintf(linkname, sizeof(linkname),
981                           "/proc/%d/fd/%d", thread->pid_, fd);
982         } else {
983                 scnprintf(linkname, sizeof(linkname),
984                           "/proc/%d/task/%d/fd/%d", thread->pid_, thread->tid, fd);
985         }
986
987         if (lstat(linkname, &st) < 0 || st.st_size + 1 > (off_t)sizeof(pathname))
988                 return -1;
989
990         ret = readlink(linkname, pathname, sizeof(pathname));
991
992         if (ret < 0 || ret > st.st_size)
993                 return -1;
994
995         pathname[ret] = '\0';
996
997         if (fd > ttrace->paths.max) {
998                 char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *));
999
1000                 if (npath == NULL)
1001                         return -1;
1002
1003                 if (ttrace->paths.max != -1) {
1004                         memset(npath + ttrace->paths.max + 1, 0,
1005                                (fd - ttrace->paths.max) * sizeof(char *));
1006                 } else {
1007                         memset(npath, 0, (fd + 1) * sizeof(char *));
1008                 }
1009
1010                 ttrace->paths.table = npath;
1011                 ttrace->paths.max   = fd;
1012         }
1013
1014         ttrace->paths.table[fd] = strdup(pathname);
1015
1016         return ttrace->paths.table[fd] != NULL ? 0 : -1;
1017 }
1018
1019 static const char *thread__fd_path(struct thread *thread, int fd, bool live)
1020 {
1021         struct thread_trace *ttrace = thread->priv;
1022
1023         if (ttrace == NULL)
1024                 return NULL;
1025
1026         if (fd < 0)
1027                 return NULL;
1028
1029         if ((fd > ttrace->paths.max || ttrace->paths.table[fd] == NULL) &&
1030             (!live || thread__read_fd_path(thread, fd)))
1031                 return NULL;
1032
1033         return ttrace->paths.table[fd];
1034 }
1035
1036 static size_t syscall_arg__scnprintf_fd(char *bf, size_t size,
1037                                         struct syscall_arg *arg)
1038 {
1039         int fd = arg->val;
1040         size_t printed = scnprintf(bf, size, "%d", fd);
1041         const char *path = thread__fd_path(arg->thread, fd, arg->trace->live);
1042
1043         if (path)
1044                 printed += scnprintf(bf + printed, size - printed, "<%s>", path);
1045
1046         return printed;
1047 }
1048
1049 static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size,
1050                                               struct syscall_arg *arg)
1051 {
1052         int fd = arg->val;
1053         size_t printed = syscall_arg__scnprintf_fd(bf, size, arg);
1054         struct thread_trace *ttrace = arg->thread->priv;
1055
1056         if (ttrace && fd >= 0 && fd <= ttrace->paths.max) {
1057                 free(ttrace->paths.table[fd]);
1058                 ttrace->paths.table[fd] = NULL;
1059         }
1060
1061         return printed;
1062 }
1063
1064 static bool trace__filter_duration(struct trace *trace, double t)
1065 {
1066         return t < (trace->duration_filter * NSEC_PER_MSEC);
1067 }
1068
1069 static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp)
1070 {
1071         double ts = (double)(tstamp - trace->base_time) / NSEC_PER_MSEC;
1072
1073         return fprintf(fp, "%10.3f ", ts);
1074 }
1075
1076 static bool done = false;
1077
1078 static void sig_handler(int sig __maybe_unused)
1079 {
1080         done = true;
1081 }
1082
1083 static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thread,
1084                                         u64 duration, u64 tstamp, FILE *fp)
1085 {
1086         size_t printed = trace__fprintf_tstamp(trace, tstamp, fp);
1087         printed += fprintf_duration(duration, fp);
1088
1089         if (trace->multiple_threads) {
1090                 if (trace->show_comm)
1091                         printed += fprintf(fp, "%.14s/", thread->comm);
1092                 printed += fprintf(fp, "%d ", thread->tid);
1093         }
1094
1095         return printed;
1096 }
1097
1098 static int trace__process_event(struct trace *trace, struct machine *machine,
1099                                 union perf_event *event)
1100 {
1101         int ret = 0;
1102
1103         switch (event->header.type) {
1104         case PERF_RECORD_LOST:
1105                 color_fprintf(trace->output, PERF_COLOR_RED,
1106                               "LOST %" PRIu64 " events!\n", event->lost.lost);
1107                 ret = machine__process_lost_event(machine, event);
1108         default:
1109                 ret = machine__process_event(machine, event);
1110                 break;
1111         }
1112
1113         return ret;
1114 }
1115
1116 static int trace__tool_process(struct perf_tool *tool,
1117                                union perf_event *event,
1118                                struct perf_sample *sample __maybe_unused,
1119                                struct machine *machine)
1120 {
1121         struct trace *trace = container_of(tool, struct trace, tool);
1122         return trace__process_event(trace, machine, event);
1123 }
1124
1125 static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
1126 {
1127         int err = symbol__init();
1128
1129         if (err)
1130                 return err;
1131
1132         trace->host = machine__new_host();
1133         if (trace->host == NULL)
1134                 return -ENOMEM;
1135
1136         if (perf_target__has_task(&trace->opts.target)) {
1137                 err = perf_event__synthesize_thread_map(&trace->tool, evlist->threads,
1138                                                         trace__tool_process,
1139                                                         trace->host);
1140         } else {
1141                 err = perf_event__synthesize_threads(&trace->tool, trace__tool_process,
1142                                                      trace->host);
1143         }
1144
1145         if (err)
1146                 symbol__exit();
1147
1148         return err;
1149 }
1150
1151 static int syscall__set_arg_fmts(struct syscall *sc)
1152 {
1153         struct format_field *field;
1154         int idx = 0;
1155
1156         sc->arg_scnprintf = calloc(sc->tp_format->format.nr_fields - 1, sizeof(void *));
1157         if (sc->arg_scnprintf == NULL)
1158                 return -1;
1159
1160         if (sc->fmt)
1161                 sc->arg_parm = sc->fmt->arg_parm;
1162
1163         for (field = sc->tp_format->format.fields->next; field; field = field->next) {
1164                 if (sc->fmt && sc->fmt->arg_scnprintf[idx])
1165                         sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx];
1166                 else if (field->flags & FIELD_IS_POINTER)
1167                         sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex;
1168                 ++idx;
1169         }
1170
1171         return 0;
1172 }
1173
1174 static int trace__read_syscall_info(struct trace *trace, int id)
1175 {
1176         char tp_name[128];
1177         struct syscall *sc;
1178         const char *name = audit_syscall_to_name(id, trace->audit_machine);
1179
1180         if (name == NULL)
1181                 return -1;
1182
1183         if (id > trace->syscalls.max) {
1184                 struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc));
1185
1186                 if (nsyscalls == NULL)
1187                         return -1;
1188
1189                 if (trace->syscalls.max != -1) {
1190                         memset(nsyscalls + trace->syscalls.max + 1, 0,
1191                                (id - trace->syscalls.max) * sizeof(*sc));
1192                 } else {
1193                         memset(nsyscalls, 0, (id + 1) * sizeof(*sc));
1194                 }
1195
1196                 trace->syscalls.table = nsyscalls;
1197                 trace->syscalls.max   = id;
1198         }
1199
1200         sc = trace->syscalls.table + id;
1201         sc->name = name;
1202
1203         if (trace->ev_qualifier) {
1204                 bool in = strlist__find(trace->ev_qualifier, name) != NULL;
1205
1206                 if (!(in ^ trace->not_ev_qualifier)) {
1207                         sc->filtered = true;
1208                         /*
1209                          * No need to do read tracepoint information since this will be
1210                          * filtered out.
1211                          */
1212                         return 0;
1213                 }
1214         }
1215
1216         sc->fmt  = syscall_fmt__find(sc->name);
1217
1218         snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name);
1219         sc->tp_format = event_format__new("syscalls", tp_name);
1220
1221         if (sc->tp_format == NULL && sc->fmt && sc->fmt->alias) {
1222                 snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->fmt->alias);
1223                 sc->tp_format = event_format__new("syscalls", tp_name);
1224         }
1225
1226         if (sc->tp_format == NULL)
1227                 return -1;
1228
1229         return syscall__set_arg_fmts(sc);
1230 }
1231
1232 static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
1233                                       unsigned long *args, struct trace *trace,
1234                                       struct thread *thread)
1235 {
1236         size_t printed = 0;
1237
1238         if (sc->tp_format != NULL) {
1239                 struct format_field *field;
1240                 u8 bit = 1;
1241                 struct syscall_arg arg = {
1242                         .idx    = 0,
1243                         .mask   = 0,
1244                         .trace  = trace,
1245                         .thread = thread,
1246                 };
1247
1248                 for (field = sc->tp_format->format.fields->next; field;
1249                      field = field->next, ++arg.idx, bit <<= 1) {
1250                         if (arg.mask & bit)
1251                                 continue;
1252                         /*
1253                          * Suppress this argument if its value is zero and
1254                          * and we don't have a string associated in an
1255                          * strarray for it.
1256                          */
1257                         if (args[arg.idx] == 0 &&
1258                             !(sc->arg_scnprintf &&
1259                               sc->arg_scnprintf[arg.idx] == SCA_STRARRAY &&
1260                               sc->arg_parm[arg.idx]))
1261                                 continue;
1262
1263                         printed += scnprintf(bf + printed, size - printed,
1264                                              "%s%s: ", printed ? ", " : "", field->name);
1265                         if (sc->arg_scnprintf && sc->arg_scnprintf[arg.idx]) {
1266                                 arg.val = args[arg.idx];
1267                                 if (sc->arg_parm)
1268                                         arg.parm = sc->arg_parm[arg.idx];
1269                                 printed += sc->arg_scnprintf[arg.idx](bf + printed,
1270                                                                       size - printed, &arg);
1271                         } else {
1272                                 printed += scnprintf(bf + printed, size - printed,
1273                                                      "%ld", args[arg.idx]);
1274                         }
1275                 }
1276         } else {
1277                 int i = 0;
1278
1279                 while (i < 6) {
1280                         printed += scnprintf(bf + printed, size - printed,
1281                                              "%sarg%d: %ld",
1282                                              printed ? ", " : "", i, args[i]);
1283                         ++i;
1284                 }
1285         }
1286
1287         return printed;
1288 }
1289
1290 typedef int (*tracepoint_handler)(struct trace *trace, struct perf_evsel *evsel,
1291                                   struct perf_sample *sample);
1292
1293 static struct syscall *trace__syscall_info(struct trace *trace,
1294                                            struct perf_evsel *evsel,
1295                                            struct perf_sample *sample)
1296 {
1297         int id = perf_evsel__intval(evsel, sample, "id");
1298
1299         if (id < 0) {
1300
1301                 /*
1302                  * XXX: Noticed on x86_64, reproduced as far back as 3.0.36, haven't tried
1303                  * before that, leaving at a higher verbosity level till that is
1304                  * explained. Reproduced with plain ftrace with:
1305                  *
1306                  * echo 1 > /t/events/raw_syscalls/sys_exit/enable
1307                  * grep "NR -1 " /t/trace_pipe
1308                  *
1309                  * After generating some load on the machine.
1310                  */
1311                 if (verbose > 1) {
1312                         static u64 n;
1313                         fprintf(trace->output, "Invalid syscall %d id, skipping (%s, %" PRIu64 ") ...\n",
1314                                 id, perf_evsel__name(evsel), ++n);
1315                 }
1316                 return NULL;
1317         }
1318
1319         if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) &&
1320             trace__read_syscall_info(trace, id))
1321                 goto out_cant_read;
1322
1323         if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL))
1324                 goto out_cant_read;
1325
1326         return &trace->syscalls.table[id];
1327
1328 out_cant_read:
1329         if (verbose) {
1330                 fprintf(trace->output, "Problems reading syscall %d", id);
1331                 if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL)
1332                         fprintf(trace->output, "(%s)", trace->syscalls.table[id].name);
1333                 fputs(" information\n", trace->output);
1334         }
1335         return NULL;
1336 }
1337
1338 static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
1339                             struct perf_sample *sample)
1340 {
1341         char *msg;
1342         void *args;
1343         size_t printed = 0;
1344         struct thread *thread;
1345         struct syscall *sc = trace__syscall_info(trace, evsel, sample);
1346         struct thread_trace *ttrace;
1347
1348         if (sc == NULL)
1349                 return -1;
1350
1351         if (sc->filtered)
1352                 return 0;
1353
1354         thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
1355         ttrace = thread__trace(thread, trace->output);
1356         if (ttrace == NULL)
1357                 return -1;
1358
1359         args = perf_evsel__rawptr(evsel, sample, "args");
1360         if (args == NULL) {
1361                 fprintf(trace->output, "Problems reading syscall arguments\n");
1362                 return -1;
1363         }
1364
1365         ttrace = thread->priv;
1366
1367         if (ttrace->entry_str == NULL) {
1368                 ttrace->entry_str = malloc(1024);
1369                 if (!ttrace->entry_str)
1370                         return -1;
1371         }
1372
1373         ttrace->entry_time = sample->time;
1374         msg = ttrace->entry_str;
1375         printed += scnprintf(msg + printed, 1024 - printed, "%s(", sc->name);
1376
1377         printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed,
1378                                            args, trace, thread);
1379
1380         if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) {
1381                 if (!trace->duration_filter) {
1382                         trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output);
1383                         fprintf(trace->output, "%-70s\n", ttrace->entry_str);
1384                 }
1385         } else
1386                 ttrace->entry_pending = true;
1387
1388         return 0;
1389 }
1390
1391 static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
1392                            struct perf_sample *sample)
1393 {
1394         int ret;
1395         u64 duration = 0;
1396         struct thread *thread;
1397         struct syscall *sc = trace__syscall_info(trace, evsel, sample);
1398         struct thread_trace *ttrace;
1399
1400         if (sc == NULL)
1401                 return -1;
1402
1403         if (sc->filtered)
1404                 return 0;
1405
1406         thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
1407         ttrace = thread__trace(thread, trace->output);
1408         if (ttrace == NULL)
1409                 return -1;
1410
1411         ret = perf_evsel__intval(evsel, sample, "ret");
1412
1413         ttrace = thread->priv;
1414
1415         ttrace->exit_time = sample->time;
1416
1417         if (ttrace->entry_time) {
1418                 duration = sample->time - ttrace->entry_time;
1419                 if (trace__filter_duration(trace, duration))
1420                         goto out;
1421         } else if (trace->duration_filter)
1422                 goto out;
1423
1424         trace__fprintf_entry_head(trace, thread, duration, sample->time, trace->output);
1425
1426         if (ttrace->entry_pending) {
1427                 fprintf(trace->output, "%-70s", ttrace->entry_str);
1428         } else {
1429                 fprintf(trace->output, " ... [");
1430                 color_fprintf(trace->output, PERF_COLOR_YELLOW, "continued");
1431                 fprintf(trace->output, "]: %s()", sc->name);
1432         }
1433
1434         if (sc->fmt == NULL) {
1435 signed_print:
1436                 fprintf(trace->output, ") = %d", ret);
1437         } else if (ret < 0 && sc->fmt->errmsg) {
1438                 char bf[256];
1439                 const char *emsg = strerror_r(-ret, bf, sizeof(bf)),
1440                            *e = audit_errno_to_name(-ret);
1441
1442                 fprintf(trace->output, ") = -1 %s %s", e, emsg);
1443         } else if (ret == 0 && sc->fmt->timeout)
1444                 fprintf(trace->output, ") = 0 Timeout");
1445         else if (sc->fmt->hexret)
1446                 fprintf(trace->output, ") = %#x", ret);
1447         else
1448                 goto signed_print;
1449
1450         fputc('\n', trace->output);
1451 out:
1452         ttrace->entry_pending = false;
1453
1454         return 0;
1455 }
1456
1457 static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evsel,
1458                                      struct perf_sample *sample)
1459 {
1460         u64 runtime = perf_evsel__intval(evsel, sample, "runtime");
1461         double runtime_ms = (double)runtime / NSEC_PER_MSEC;
1462         struct thread *thread = machine__findnew_thread(trace->host,
1463                                                         sample->pid,
1464                                                         sample->tid);
1465         struct thread_trace *ttrace = thread__trace(thread, trace->output);
1466
1467         if (ttrace == NULL)
1468                 goto out_dump;
1469
1470         ttrace->runtime_ms += runtime_ms;
1471         trace->runtime_ms += runtime_ms;
1472         return 0;
1473
1474 out_dump:
1475         fprintf(trace->output, "%s: comm=%s,pid=%u,runtime=%" PRIu64 ",vruntime=%" PRIu64 ")\n",
1476                evsel->name,
1477                perf_evsel__strval(evsel, sample, "comm"),
1478                (pid_t)perf_evsel__intval(evsel, sample, "pid"),
1479                runtime,
1480                perf_evsel__intval(evsel, sample, "vruntime"));
1481         return 0;
1482 }
1483
1484 static bool skip_sample(struct trace *trace, struct perf_sample *sample)
1485 {
1486         if ((trace->pid_list && intlist__find(trace->pid_list, sample->pid)) ||
1487             (trace->tid_list && intlist__find(trace->tid_list, sample->tid)))
1488                 return false;
1489
1490         if (trace->pid_list || trace->tid_list)
1491                 return true;
1492
1493         return false;
1494 }
1495
1496 static int trace__process_sample(struct perf_tool *tool,
1497                                  union perf_event *event __maybe_unused,
1498                                  struct perf_sample *sample,
1499                                  struct perf_evsel *evsel,
1500                                  struct machine *machine __maybe_unused)
1501 {
1502         struct trace *trace = container_of(tool, struct trace, tool);
1503         int err = 0;
1504
1505         tracepoint_handler handler = evsel->handler.func;
1506
1507         if (skip_sample(trace, sample))
1508                 return 0;
1509
1510         if (!trace->full_time && trace->base_time == 0)
1511                 trace->base_time = sample->time;
1512
1513         if (handler)
1514                 handler(trace, evsel, sample);
1515
1516         return err;
1517 }
1518
1519 static bool
1520 perf_session__has_tp(struct perf_session *session, const char *name)
1521 {
1522         struct perf_evsel *evsel;
1523
1524         evsel = perf_evlist__find_tracepoint_by_name(session->evlist, name);
1525
1526         return evsel != NULL;
1527 }
1528
1529 static int parse_target_str(struct trace *trace)
1530 {
1531         if (trace->opts.target.pid) {
1532                 trace->pid_list = intlist__new(trace->opts.target.pid);
1533                 if (trace->pid_list == NULL) {
1534                         pr_err("Error parsing process id string\n");
1535                         return -EINVAL;
1536                 }
1537         }
1538
1539         if (trace->opts.target.tid) {
1540                 trace->tid_list = intlist__new(trace->opts.target.tid);
1541                 if (trace->tid_list == NULL) {
1542                         pr_err("Error parsing thread id string\n");
1543                         return -EINVAL;
1544                 }
1545         }
1546
1547         return 0;
1548 }
1549
1550 static int trace__record(int argc, const char **argv)
1551 {
1552         unsigned int rec_argc, i, j;
1553         const char **rec_argv;
1554         const char * const record_args[] = {
1555                 "record",
1556                 "-R",
1557                 "-m", "1024",
1558                 "-c", "1",
1559                 "-e", "raw_syscalls:sys_enter,raw_syscalls:sys_exit",
1560         };
1561
1562         rec_argc = ARRAY_SIZE(record_args) + argc;
1563         rec_argv = calloc(rec_argc + 1, sizeof(char *));
1564
1565         if (rec_argv == NULL)
1566                 return -ENOMEM;
1567
1568         for (i = 0; i < ARRAY_SIZE(record_args); i++)
1569                 rec_argv[i] = record_args[i];
1570
1571         for (j = 0; j < (unsigned int)argc; j++, i++)
1572                 rec_argv[i] = argv[j];
1573
1574         return cmd_record(i, rec_argv, NULL);
1575 }
1576
1577 static int trace__run(struct trace *trace, int argc, const char **argv)
1578 {
1579         struct perf_evlist *evlist = perf_evlist__new();
1580         struct perf_evsel *evsel;
1581         int err = -1, i;
1582         unsigned long before;
1583         const bool forks = argc > 0;
1584
1585         trace->live = true;
1586
1587         if (evlist == NULL) {
1588                 fprintf(trace->output, "Not enough memory to run!\n");
1589                 goto out;
1590         }
1591
1592         if (perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_enter", trace__sys_enter) ||
1593             perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_exit", trace__sys_exit)) {
1594                 fprintf(trace->output, "Couldn't read the raw_syscalls tracepoints information!\n");
1595                 goto out_delete_evlist;
1596         }
1597
1598         if (trace->sched &&
1599             perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime",
1600                                    trace__sched_stat_runtime)) {
1601                 fprintf(trace->output, "Couldn't read the sched_stat_runtime tracepoint information!\n");
1602                 goto out_delete_evlist;
1603         }
1604
1605         err = perf_evlist__create_maps(evlist, &trace->opts.target);
1606         if (err < 0) {
1607                 fprintf(trace->output, "Problems parsing the target to trace, check your options!\n");
1608                 goto out_delete_evlist;
1609         }
1610
1611         err = trace__symbols_init(trace, evlist);
1612         if (err < 0) {
1613                 fprintf(trace->output, "Problems initializing symbol libraries!\n");
1614                 goto out_delete_maps;
1615         }
1616
1617         perf_evlist__config(evlist, &trace->opts);
1618
1619         signal(SIGCHLD, sig_handler);
1620         signal(SIGINT, sig_handler);
1621
1622         if (forks) {
1623                 err = perf_evlist__prepare_workload(evlist, &trace->opts.target,
1624                                                     argv, false, false);
1625                 if (err < 0) {
1626                         fprintf(trace->output, "Couldn't run the workload!\n");
1627                         goto out_delete_maps;
1628                 }
1629         }
1630
1631         err = perf_evlist__open(evlist);
1632         if (err < 0) {
1633                 fprintf(trace->output, "Couldn't create the events: %s\n", strerror(errno));
1634                 goto out_delete_maps;
1635         }
1636
1637         err = perf_evlist__mmap(evlist, UINT_MAX, false);
1638         if (err < 0) {
1639                 fprintf(trace->output, "Couldn't mmap the events: %s\n", strerror(errno));
1640                 goto out_close_evlist;
1641         }
1642
1643         perf_evlist__enable(evlist);
1644
1645         if (forks)
1646                 perf_evlist__start_workload(evlist);
1647
1648         trace->multiple_threads = evlist->threads->map[0] == -1 || evlist->threads->nr > 1;
1649 again:
1650         before = trace->nr_events;
1651
1652         for (i = 0; i < evlist->nr_mmaps; i++) {
1653                 union perf_event *event;
1654
1655                 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
1656                         const u32 type = event->header.type;
1657                         tracepoint_handler handler;
1658                         struct perf_sample sample;
1659
1660                         ++trace->nr_events;
1661
1662                         err = perf_evlist__parse_sample(evlist, event, &sample);
1663                         if (err) {
1664                                 fprintf(trace->output, "Can't parse sample, err = %d, skipping...\n", err);
1665                                 continue;
1666                         }
1667
1668                         if (!trace->full_time && trace->base_time == 0)
1669                                 trace->base_time = sample.time;
1670
1671                         if (type != PERF_RECORD_SAMPLE) {
1672                                 trace__process_event(trace, trace->host, event);
1673                                 continue;
1674                         }
1675
1676                         evsel = perf_evlist__id2evsel(evlist, sample.id);
1677                         if (evsel == NULL) {
1678                                 fprintf(trace->output, "Unknown tp ID %" PRIu64 ", skipping...\n", sample.id);
1679                                 continue;
1680                         }
1681
1682                         if (sample.raw_data == NULL) {
1683                                 fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
1684                                        perf_evsel__name(evsel), sample.tid,
1685                                        sample.cpu, sample.raw_size);
1686                                 continue;
1687                         }
1688
1689                         handler = evsel->handler.func;
1690                         handler(trace, evsel, &sample);
1691
1692                         if (done)
1693                                 goto out_unmap_evlist;
1694                 }
1695         }
1696
1697         if (trace->nr_events == before) {
1698                 if (done)
1699                         goto out_unmap_evlist;
1700
1701                 poll(evlist->pollfd, evlist->nr_fds, -1);
1702         }
1703
1704         if (done)
1705                 perf_evlist__disable(evlist);
1706
1707         goto again;
1708
1709 out_unmap_evlist:
1710         perf_evlist__munmap(evlist);
1711 out_close_evlist:
1712         perf_evlist__close(evlist);
1713 out_delete_maps:
1714         perf_evlist__delete_maps(evlist);
1715 out_delete_evlist:
1716         perf_evlist__delete(evlist);
1717 out:
1718         trace->live = false;
1719         return err;
1720 }
1721
1722 static int trace__replay(struct trace *trace)
1723 {
1724         const struct perf_evsel_str_handler handlers[] = {
1725                 { "raw_syscalls:sys_enter",  trace__sys_enter, },
1726                 { "raw_syscalls:sys_exit",   trace__sys_exit, },
1727         };
1728
1729         struct perf_session *session;
1730         int err = -1;
1731
1732         trace->tool.sample        = trace__process_sample;
1733         trace->tool.mmap          = perf_event__process_mmap;
1734         trace->tool.mmap2         = perf_event__process_mmap2;
1735         trace->tool.comm          = perf_event__process_comm;
1736         trace->tool.exit          = perf_event__process_exit;
1737         trace->tool.fork          = perf_event__process_fork;
1738         trace->tool.attr          = perf_event__process_attr;
1739         trace->tool.tracing_data = perf_event__process_tracing_data;
1740         trace->tool.build_id      = perf_event__process_build_id;
1741
1742         trace->tool.ordered_samples = true;
1743         trace->tool.ordering_requires_timestamps = true;
1744
1745         /* add tid to output */
1746         trace->multiple_threads = true;
1747
1748         if (symbol__init() < 0)
1749                 return -1;
1750
1751         session = perf_session__new(input_name, O_RDONLY, 0, false,
1752                                     &trace->tool);
1753         if (session == NULL)
1754                 return -ENOMEM;
1755
1756         trace->host = &session->machines.host;
1757
1758         err = perf_session__set_tracepoints_handlers(session, handlers);
1759         if (err)
1760                 goto out;
1761
1762         if (!perf_session__has_tp(session, "raw_syscalls:sys_enter")) {
1763                 pr_err("Data file does not have raw_syscalls:sys_enter events\n");
1764                 goto out;
1765         }
1766
1767         if (!perf_session__has_tp(session, "raw_syscalls:sys_exit")) {
1768                 pr_err("Data file does not have raw_syscalls:sys_exit events\n");
1769                 goto out;
1770         }
1771
1772         err = parse_target_str(trace);
1773         if (err != 0)
1774                 goto out;
1775
1776         setup_pager();
1777
1778         err = perf_session__process_events(session, &trace->tool);
1779         if (err)
1780                 pr_err("Failed to process events, error %d", err);
1781
1782 out:
1783         perf_session__delete(session);
1784
1785         return err;
1786 }
1787
1788 static size_t trace__fprintf_threads_header(FILE *fp)
1789 {
1790         size_t printed;
1791
1792         printed  = fprintf(fp, "\n _____________________________________________________________________\n");
1793         printed += fprintf(fp," __)    Summary of events    (__\n\n");
1794         printed += fprintf(fp,"              [ task - pid ]     [ events ] [ ratio ]  [ runtime ]\n");
1795         printed += fprintf(fp," _____________________________________________________________________\n\n");
1796
1797         return printed;
1798 }
1799
1800 /* struct used to pass data to per-thread function */
1801 struct summary_data {
1802         FILE *fp;
1803         struct trace *trace;
1804         size_t printed;
1805 };
1806
1807 static int trace__fprintf_one_thread(struct thread *thread, void *priv)
1808 {
1809         struct summary_data *data = priv;
1810         FILE *fp = data->fp;
1811         size_t printed = data->printed;
1812         struct trace *trace = data->trace;
1813         struct thread_trace *ttrace = thread->priv;
1814         const char *color;
1815         double ratio;
1816
1817         if (ttrace == NULL)
1818                 return 0;
1819
1820         ratio = (double)ttrace->nr_events / trace->nr_events * 100.0;
1821
1822         color = PERF_COLOR_NORMAL;
1823         if (ratio > 50.0)
1824                 color = PERF_COLOR_RED;
1825         else if (ratio > 25.0)
1826                 color = PERF_COLOR_GREEN;
1827         else if (ratio > 5.0)
1828                 color = PERF_COLOR_YELLOW;
1829
1830         printed += color_fprintf(fp, color, "%20s", thread->comm);
1831         printed += fprintf(fp, " - %-5d :%11lu   [", thread->tid, ttrace->nr_events);
1832         printed += color_fprintf(fp, color, "%5.1f%%", ratio);
1833         printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms);
1834
1835         data->printed += printed;
1836
1837         return 0;
1838 }
1839
1840 static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
1841 {
1842         struct summary_data data = {
1843                 .fp = fp,
1844                 .trace = trace
1845         };
1846         data.printed = trace__fprintf_threads_header(fp);
1847
1848         machine__for_each_thread(trace->host, trace__fprintf_one_thread, &data);
1849
1850         return data.printed;
1851 }
1852
1853 static int trace__set_duration(const struct option *opt, const char *str,
1854                                int unset __maybe_unused)
1855 {
1856         struct trace *trace = opt->value;
1857
1858         trace->duration_filter = atof(str);
1859         return 0;
1860 }
1861
1862 static int trace__open_output(struct trace *trace, const char *filename)
1863 {
1864         struct stat st;
1865
1866         if (!stat(filename, &st) && st.st_size) {
1867                 char oldname[PATH_MAX];
1868
1869                 scnprintf(oldname, sizeof(oldname), "%s.old", filename);
1870                 unlink(oldname);
1871                 rename(filename, oldname);
1872         }
1873
1874         trace->output = fopen(filename, "w");
1875
1876         return trace->output == NULL ? -errno : 0;
1877 }
1878
1879 int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
1880 {
1881         const char * const trace_usage[] = {
1882                 "perf trace [<options>] [<command>]",
1883                 "perf trace [<options>] -- <command> [<options>]",
1884                 "perf trace record [<options>] [<command>]",
1885                 "perf trace record [<options>] -- <command> [<options>]",
1886                 NULL
1887         };
1888         struct trace trace = {
1889                 .audit_machine = audit_detect_machine(),
1890                 .syscalls = {
1891                         . max = -1,
1892                 },
1893                 .opts = {
1894                         .target = {
1895                                 .uid       = UINT_MAX,
1896                                 .uses_mmap = true,
1897                         },
1898                         .user_freq     = UINT_MAX,
1899                         .user_interval = ULLONG_MAX,
1900                         .no_delay      = true,
1901                         .mmap_pages    = 1024,
1902                 },
1903                 .output = stdout,
1904                 .show_comm = true,
1905         };
1906         const char *output_name = NULL;
1907         const char *ev_qualifier_str = NULL;
1908         const struct option trace_options[] = {
1909         OPT_BOOLEAN(0, "comm", &trace.show_comm,
1910                     "show the thread COMM next to its id"),
1911         OPT_STRING('e', "expr", &ev_qualifier_str, "expr",
1912                     "list of events to trace"),
1913         OPT_STRING('o', "output", &output_name, "file", "output file name"),
1914         OPT_STRING('i', "input", &input_name, "file", "Analyze events in file"),
1915         OPT_STRING('p', "pid", &trace.opts.target.pid, "pid",
1916                     "trace events on existing process id"),
1917         OPT_STRING('t', "tid", &trace.opts.target.tid, "tid",
1918                     "trace events on existing thread id"),
1919         OPT_BOOLEAN('a', "all-cpus", &trace.opts.target.system_wide,
1920                     "system-wide collection from all CPUs"),
1921         OPT_STRING('C', "cpu", &trace.opts.target.cpu_list, "cpu",
1922                     "list of cpus to monitor"),
1923         OPT_BOOLEAN(0, "no-inherit", &trace.opts.no_inherit,
1924                     "child tasks do not inherit counters"),
1925         OPT_CALLBACK('m', "mmap-pages", &trace.opts.mmap_pages, "pages",
1926                      "number of mmap data pages",
1927                      perf_evlist__parse_mmap_pages),
1928         OPT_STRING('u', "uid", &trace.opts.target.uid_str, "user",
1929                    "user to profile"),
1930         OPT_CALLBACK(0, "duration", &trace, "float",
1931                      "show only events with duration > N.M ms",
1932                      trace__set_duration),
1933         OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"),
1934         OPT_INCR('v', "verbose", &verbose, "be more verbose"),
1935         OPT_BOOLEAN('T', "time", &trace.full_time,
1936                     "Show full timestamp, not time relative to first start"),
1937         OPT_END()
1938         };
1939         int err;
1940         char bf[BUFSIZ];
1941
1942         if ((argc > 1) && (strcmp(argv[1], "record") == 0))
1943                 return trace__record(argc-2, &argv[2]);
1944
1945         argc = parse_options(argc, argv, trace_options, trace_usage, 0);
1946
1947         if (output_name != NULL) {
1948                 err = trace__open_output(&trace, output_name);
1949                 if (err < 0) {
1950                         perror("failed to create output file");
1951                         goto out;
1952                 }
1953         }
1954
1955         if (ev_qualifier_str != NULL) {
1956                 const char *s = ev_qualifier_str;
1957
1958                 trace.not_ev_qualifier = *s == '!';
1959                 if (trace.not_ev_qualifier)
1960                         ++s;
1961                 trace.ev_qualifier = strlist__new(true, s);
1962                 if (trace.ev_qualifier == NULL) {
1963                         fputs("Not enough memory to parse event qualifier",
1964                               trace.output);
1965                         err = -ENOMEM;
1966                         goto out_close;
1967                 }
1968         }
1969
1970         err = perf_target__validate(&trace.opts.target);
1971         if (err) {
1972                 perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));
1973                 fprintf(trace.output, "%s", bf);
1974                 goto out_close;
1975         }
1976
1977         err = perf_target__parse_uid(&trace.opts.target);
1978         if (err) {
1979                 perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));
1980                 fprintf(trace.output, "%s", bf);
1981                 goto out_close;
1982         }
1983
1984         if (!argc && perf_target__none(&trace.opts.target))
1985                 trace.opts.target.system_wide = true;
1986
1987         if (input_name)
1988                 err = trace__replay(&trace);
1989         else
1990                 err = trace__run(&trace, argc, argv);
1991
1992         if (trace.sched && !err)
1993                 trace__fprintf_thread_summary(&trace, trace.output);
1994
1995 out_close:
1996         if (output_name != NULL)
1997                 fclose(trace.output);
1998 out:
1999         return err;
2000 }