xref: /openbmc/linux/tools/perf/builtin-trace.c (revision a2cce7a9)
1 /*
2  * builtin-trace.c
3  *
4  * Builtin 'trace' command:
5  *
6  * Display a continuously updated trace of any workload, CPU, specific PID,
7  * system wide, etc.  Default format is loosely strace like, but any other
8  * event may be specified using --event.
9  *
10  * Copyright (C) 2012, 2013, 2014, 2015 Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
11  *
12  * Initially based on the 'trace' prototype by Thomas Gleixner:
13  *
14  * http://lwn.net/Articles/415728/ ("Announcing a new utility: 'trace'")
15  *
16  * Released under the GPL v2. (and only v2, not any later version)
17  */
18 
19 #include <traceevent/event-parse.h>
20 #include "builtin.h"
21 #include "util/color.h"
22 #include "util/debug.h"
23 #include "util/evlist.h"
24 #include "util/exec_cmd.h"
25 #include "util/machine.h"
26 #include "util/session.h"
27 #include "util/thread.h"
28 #include "util/parse-options.h"
29 #include "util/strlist.h"
30 #include "util/intlist.h"
31 #include "util/thread_map.h"
32 #include "util/stat.h"
33 #include "trace-event.h"
34 #include "util/parse-events.h"
35 
36 #include <libaudit.h>
37 #include <stdlib.h>
38 #include <sys/mman.h>
39 #include <linux/futex.h>
40 
41 /* For older distros: */
42 #ifndef MAP_STACK
43 # define MAP_STACK		0x20000
44 #endif
45 
46 #ifndef MADV_HWPOISON
47 # define MADV_HWPOISON		100
48 
49 #endif
50 
51 #ifndef MADV_MERGEABLE
52 # define MADV_MERGEABLE		12
53 #endif
54 
55 #ifndef MADV_UNMERGEABLE
56 # define MADV_UNMERGEABLE	13
57 #endif
58 
59 #ifndef EFD_SEMAPHORE
60 # define EFD_SEMAPHORE		1
61 #endif
62 
63 #ifndef EFD_NONBLOCK
64 # define EFD_NONBLOCK		00004000
65 #endif
66 
67 #ifndef EFD_CLOEXEC
68 # define EFD_CLOEXEC		02000000
69 #endif
70 
71 #ifndef O_CLOEXEC
72 # define O_CLOEXEC		02000000
73 #endif
74 
75 #ifndef SOCK_DCCP
76 # define SOCK_DCCP		6
77 #endif
78 
79 #ifndef SOCK_CLOEXEC
80 # define SOCK_CLOEXEC		02000000
81 #endif
82 
83 #ifndef SOCK_NONBLOCK
84 # define SOCK_NONBLOCK		00004000
85 #endif
86 
87 #ifndef MSG_CMSG_CLOEXEC
88 # define MSG_CMSG_CLOEXEC	0x40000000
89 #endif
90 
91 #ifndef PERF_FLAG_FD_NO_GROUP
92 # define PERF_FLAG_FD_NO_GROUP		(1UL << 0)
93 #endif
94 
95 #ifndef PERF_FLAG_FD_OUTPUT
96 # define PERF_FLAG_FD_OUTPUT		(1UL << 1)
97 #endif
98 
99 #ifndef PERF_FLAG_PID_CGROUP
100 # define PERF_FLAG_PID_CGROUP		(1UL << 2) /* pid=cgroup id, per-cpu mode only */
101 #endif
102 
103 #ifndef PERF_FLAG_FD_CLOEXEC
104 # define PERF_FLAG_FD_CLOEXEC		(1UL << 3) /* O_CLOEXEC */
105 #endif
106 
107 
108 struct tp_field {
109 	int offset;
110 	union {
111 		u64 (*integer)(struct tp_field *field, struct perf_sample *sample);
112 		void *(*pointer)(struct tp_field *field, struct perf_sample *sample);
113 	};
114 };
115 
116 #define TP_UINT_FIELD(bits) \
117 static u64 tp_field__u##bits(struct tp_field *field, struct perf_sample *sample) \
118 { \
119 	u##bits value; \
120 	memcpy(&value, sample->raw_data + field->offset, sizeof(value)); \
121 	return value;  \
122 }
123 
124 TP_UINT_FIELD(8);
125 TP_UINT_FIELD(16);
126 TP_UINT_FIELD(32);
127 TP_UINT_FIELD(64);
128 
129 #define TP_UINT_FIELD__SWAPPED(bits) \
130 static u64 tp_field__swapped_u##bits(struct tp_field *field, struct perf_sample *sample) \
131 { \
132 	u##bits value; \
133 	memcpy(&value, sample->raw_data + field->offset, sizeof(value)); \
134 	return bswap_##bits(value);\
135 }
136 
137 TP_UINT_FIELD__SWAPPED(16);
138 TP_UINT_FIELD__SWAPPED(32);
139 TP_UINT_FIELD__SWAPPED(64);
140 
141 static int tp_field__init_uint(struct tp_field *field,
142 			       struct format_field *format_field,
143 			       bool needs_swap)
144 {
145 	field->offset = format_field->offset;
146 
147 	switch (format_field->size) {
148 	case 1:
149 		field->integer = tp_field__u8;
150 		break;
151 	case 2:
152 		field->integer = needs_swap ? tp_field__swapped_u16 : tp_field__u16;
153 		break;
154 	case 4:
155 		field->integer = needs_swap ? tp_field__swapped_u32 : tp_field__u32;
156 		break;
157 	case 8:
158 		field->integer = needs_swap ? tp_field__swapped_u64 : tp_field__u64;
159 		break;
160 	default:
161 		return -1;
162 	}
163 
164 	return 0;
165 }
166 
167 static void *tp_field__ptr(struct tp_field *field, struct perf_sample *sample)
168 {
169 	return sample->raw_data + field->offset;
170 }
171 
172 static int tp_field__init_ptr(struct tp_field *field, struct format_field *format_field)
173 {
174 	field->offset = format_field->offset;
175 	field->pointer = tp_field__ptr;
176 	return 0;
177 }
178 
179 struct syscall_tp {
180 	struct tp_field id;
181 	union {
182 		struct tp_field args, ret;
183 	};
184 };
185 
186 static int perf_evsel__init_tp_uint_field(struct perf_evsel *evsel,
187 					  struct tp_field *field,
188 					  const char *name)
189 {
190 	struct format_field *format_field = perf_evsel__field(evsel, name);
191 
192 	if (format_field == NULL)
193 		return -1;
194 
195 	return tp_field__init_uint(field, format_field, evsel->needs_swap);
196 }
197 
198 #define perf_evsel__init_sc_tp_uint_field(evsel, name) \
199 	({ struct syscall_tp *sc = evsel->priv;\
200 	   perf_evsel__init_tp_uint_field(evsel, &sc->name, #name); })
201 
202 static int perf_evsel__init_tp_ptr_field(struct perf_evsel *evsel,
203 					 struct tp_field *field,
204 					 const char *name)
205 {
206 	struct format_field *format_field = perf_evsel__field(evsel, name);
207 
208 	if (format_field == NULL)
209 		return -1;
210 
211 	return tp_field__init_ptr(field, format_field);
212 }
213 
214 #define perf_evsel__init_sc_tp_ptr_field(evsel, name) \
215 	({ struct syscall_tp *sc = evsel->priv;\
216 	   perf_evsel__init_tp_ptr_field(evsel, &sc->name, #name); })
217 
218 static void perf_evsel__delete_priv(struct perf_evsel *evsel)
219 {
220 	zfree(&evsel->priv);
221 	perf_evsel__delete(evsel);
222 }
223 
224 static int perf_evsel__init_syscall_tp(struct perf_evsel *evsel, void *handler)
225 {
226 	evsel->priv = malloc(sizeof(struct syscall_tp));
227 	if (evsel->priv != NULL) {
228 		if (perf_evsel__init_sc_tp_uint_field(evsel, id))
229 			goto out_delete;
230 
231 		evsel->handler = handler;
232 		return 0;
233 	}
234 
235 	return -ENOMEM;
236 
237 out_delete:
238 	zfree(&evsel->priv);
239 	return -ENOENT;
240 }
241 
242 static struct perf_evsel *perf_evsel__syscall_newtp(const char *direction, void *handler)
243 {
244 	struct perf_evsel *evsel = perf_evsel__newtp("raw_syscalls", direction);
245 
246 	/* older kernel (e.g., RHEL6) use syscalls:{enter,exit} */
247 	if (evsel == NULL)
248 		evsel = perf_evsel__newtp("syscalls", direction);
249 
250 	if (evsel) {
251 		if (perf_evsel__init_syscall_tp(evsel, handler))
252 			goto out_delete;
253 	}
254 
255 	return evsel;
256 
257 out_delete:
258 	perf_evsel__delete_priv(evsel);
259 	return NULL;
260 }
261 
262 #define perf_evsel__sc_tp_uint(evsel, name, sample) \
263 	({ struct syscall_tp *fields = evsel->priv; \
264 	   fields->name.integer(&fields->name, sample); })
265 
266 #define perf_evsel__sc_tp_ptr(evsel, name, sample) \
267 	({ struct syscall_tp *fields = evsel->priv; \
268 	   fields->name.pointer(&fields->name, sample); })
269 
270 struct syscall_arg {
271 	unsigned long val;
272 	struct thread *thread;
273 	struct trace  *trace;
274 	void	      *parm;
275 	u8	      idx;
276 	u8	      mask;
277 };
278 
279 struct strarray {
280 	int	    offset;
281 	int	    nr_entries;
282 	const char **entries;
283 };
284 
285 #define DEFINE_STRARRAY(array) struct strarray strarray__##array = { \
286 	.nr_entries = ARRAY_SIZE(array), \
287 	.entries = array, \
288 }
289 
290 #define DEFINE_STRARRAY_OFFSET(array, off) struct strarray strarray__##array = { \
291 	.offset	    = off, \
292 	.nr_entries = ARRAY_SIZE(array), \
293 	.entries = array, \
294 }
295 
296 static size_t __syscall_arg__scnprintf_strarray(char *bf, size_t size,
297 						const char *intfmt,
298 					        struct syscall_arg *arg)
299 {
300 	struct strarray *sa = arg->parm;
301 	int idx = arg->val - sa->offset;
302 
303 	if (idx < 0 || idx >= sa->nr_entries)
304 		return scnprintf(bf, size, intfmt, arg->val);
305 
306 	return scnprintf(bf, size, "%s", sa->entries[idx]);
307 }
308 
309 static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size,
310 					      struct syscall_arg *arg)
311 {
312 	return __syscall_arg__scnprintf_strarray(bf, size, "%d", arg);
313 }
314 
315 #define SCA_STRARRAY syscall_arg__scnprintf_strarray
316 
317 #if defined(__i386__) || defined(__x86_64__)
318 /*
319  * FIXME: Make this available to all arches as soon as the ioctl beautifier
320  * 	  gets rewritten to support all arches.
321  */
322 static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size,
323 						 struct syscall_arg *arg)
324 {
325 	return __syscall_arg__scnprintf_strarray(bf, size, "%#x", arg);
326 }
327 
328 #define SCA_STRHEXARRAY syscall_arg__scnprintf_strhexarray
329 #endif /* defined(__i386__) || defined(__x86_64__) */
330 
331 static size_t syscall_arg__scnprintf_fd(char *bf, size_t size,
332 					struct syscall_arg *arg);
333 
334 #define SCA_FD syscall_arg__scnprintf_fd
335 
336 static size_t syscall_arg__scnprintf_fd_at(char *bf, size_t size,
337 					   struct syscall_arg *arg)
338 {
339 	int fd = arg->val;
340 
341 	if (fd == AT_FDCWD)
342 		return scnprintf(bf, size, "CWD");
343 
344 	return syscall_arg__scnprintf_fd(bf, size, arg);
345 }
346 
347 #define SCA_FDAT syscall_arg__scnprintf_fd_at
348 
349 static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size,
350 					      struct syscall_arg *arg);
351 
352 #define SCA_CLOSE_FD syscall_arg__scnprintf_close_fd
353 
354 static size_t syscall_arg__scnprintf_hex(char *bf, size_t size,
355 					 struct syscall_arg *arg)
356 {
357 	return scnprintf(bf, size, "%#lx", arg->val);
358 }
359 
360 #define SCA_HEX syscall_arg__scnprintf_hex
361 
362 static size_t syscall_arg__scnprintf_int(char *bf, size_t size,
363 					 struct syscall_arg *arg)
364 {
365 	return scnprintf(bf, size, "%d", arg->val);
366 }
367 
368 #define SCA_INT syscall_arg__scnprintf_int
369 
370 static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
371 					       struct syscall_arg *arg)
372 {
373 	int printed = 0, prot = arg->val;
374 
375 	if (prot == PROT_NONE)
376 		return scnprintf(bf, size, "NONE");
377 #define	P_MMAP_PROT(n) \
378 	if (prot & PROT_##n) { \
379 		printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
380 		prot &= ~PROT_##n; \
381 	}
382 
383 	P_MMAP_PROT(EXEC);
384 	P_MMAP_PROT(READ);
385 	P_MMAP_PROT(WRITE);
386 #ifdef PROT_SEM
387 	P_MMAP_PROT(SEM);
388 #endif
389 	P_MMAP_PROT(GROWSDOWN);
390 	P_MMAP_PROT(GROWSUP);
391 #undef P_MMAP_PROT
392 
393 	if (prot)
394 		printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", prot);
395 
396 	return printed;
397 }
398 
399 #define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot
400 
401 static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
402 						struct syscall_arg *arg)
403 {
404 	int printed = 0, flags = arg->val;
405 
406 #define	P_MMAP_FLAG(n) \
407 	if (flags & MAP_##n) { \
408 		printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
409 		flags &= ~MAP_##n; \
410 	}
411 
412 	P_MMAP_FLAG(SHARED);
413 	P_MMAP_FLAG(PRIVATE);
414 #ifdef MAP_32BIT
415 	P_MMAP_FLAG(32BIT);
416 #endif
417 	P_MMAP_FLAG(ANONYMOUS);
418 	P_MMAP_FLAG(DENYWRITE);
419 	P_MMAP_FLAG(EXECUTABLE);
420 	P_MMAP_FLAG(FILE);
421 	P_MMAP_FLAG(FIXED);
422 	P_MMAP_FLAG(GROWSDOWN);
423 #ifdef MAP_HUGETLB
424 	P_MMAP_FLAG(HUGETLB);
425 #endif
426 	P_MMAP_FLAG(LOCKED);
427 	P_MMAP_FLAG(NONBLOCK);
428 	P_MMAP_FLAG(NORESERVE);
429 	P_MMAP_FLAG(POPULATE);
430 	P_MMAP_FLAG(STACK);
431 #ifdef MAP_UNINITIALIZED
432 	P_MMAP_FLAG(UNINITIALIZED);
433 #endif
434 #undef P_MMAP_FLAG
435 
436 	if (flags)
437 		printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
438 
439 	return printed;
440 }
441 
442 #define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags
443 
444 static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size,
445 						  struct syscall_arg *arg)
446 {
447 	int printed = 0, flags = arg->val;
448 
449 #define P_MREMAP_FLAG(n) \
450 	if (flags & MREMAP_##n) { \
451 		printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
452 		flags &= ~MREMAP_##n; \
453 	}
454 
455 	P_MREMAP_FLAG(MAYMOVE);
456 #ifdef MREMAP_FIXED
457 	P_MREMAP_FLAG(FIXED);
458 #endif
459 #undef P_MREMAP_FLAG
460 
461 	if (flags)
462 		printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
463 
464 	return printed;
465 }
466 
467 #define SCA_MREMAP_FLAGS syscall_arg__scnprintf_mremap_flags
468 
469 static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
470 						      struct syscall_arg *arg)
471 {
472 	int behavior = arg->val;
473 
474 	switch (behavior) {
475 #define	P_MADV_BHV(n) case MADV_##n: return scnprintf(bf, size, #n)
476 	P_MADV_BHV(NORMAL);
477 	P_MADV_BHV(RANDOM);
478 	P_MADV_BHV(SEQUENTIAL);
479 	P_MADV_BHV(WILLNEED);
480 	P_MADV_BHV(DONTNEED);
481 	P_MADV_BHV(REMOVE);
482 	P_MADV_BHV(DONTFORK);
483 	P_MADV_BHV(DOFORK);
484 	P_MADV_BHV(HWPOISON);
485 #ifdef MADV_SOFT_OFFLINE
486 	P_MADV_BHV(SOFT_OFFLINE);
487 #endif
488 	P_MADV_BHV(MERGEABLE);
489 	P_MADV_BHV(UNMERGEABLE);
490 #ifdef MADV_HUGEPAGE
491 	P_MADV_BHV(HUGEPAGE);
492 #endif
493 #ifdef MADV_NOHUGEPAGE
494 	P_MADV_BHV(NOHUGEPAGE);
495 #endif
496 #ifdef MADV_DONTDUMP
497 	P_MADV_BHV(DONTDUMP);
498 #endif
499 #ifdef MADV_DODUMP
500 	P_MADV_BHV(DODUMP);
501 #endif
502 #undef P_MADV_PHV
503 	default: break;
504 	}
505 
506 	return scnprintf(bf, size, "%#x", behavior);
507 }
508 
509 #define SCA_MADV_BHV syscall_arg__scnprintf_madvise_behavior
510 
511 static size_t syscall_arg__scnprintf_flock(char *bf, size_t size,
512 					   struct syscall_arg *arg)
513 {
514 	int printed = 0, op = arg->val;
515 
516 	if (op == 0)
517 		return scnprintf(bf, size, "NONE");
518 #define	P_CMD(cmd) \
519 	if ((op & LOCK_##cmd) == LOCK_##cmd) { \
520 		printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #cmd); \
521 		op &= ~LOCK_##cmd; \
522 	}
523 
524 	P_CMD(SH);
525 	P_CMD(EX);
526 	P_CMD(NB);
527 	P_CMD(UN);
528 	P_CMD(MAND);
529 	P_CMD(RW);
530 	P_CMD(READ);
531 	P_CMD(WRITE);
532 #undef P_OP
533 
534 	if (op)
535 		printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", op);
536 
537 	return printed;
538 }
539 
540 #define SCA_FLOCK syscall_arg__scnprintf_flock
541 
542 static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct syscall_arg *arg)
543 {
544 	enum syscall_futex_args {
545 		SCF_UADDR   = (1 << 0),
546 		SCF_OP	    = (1 << 1),
547 		SCF_VAL	    = (1 << 2),
548 		SCF_TIMEOUT = (1 << 3),
549 		SCF_UADDR2  = (1 << 4),
550 		SCF_VAL3    = (1 << 5),
551 	};
552 	int op = arg->val;
553 	int cmd = op & FUTEX_CMD_MASK;
554 	size_t printed = 0;
555 
556 	switch (cmd) {
557 #define	P_FUTEX_OP(n) case FUTEX_##n: printed = scnprintf(bf, size, #n);
558 	P_FUTEX_OP(WAIT);	    arg->mask |= SCF_VAL3|SCF_UADDR2;		  break;
559 	P_FUTEX_OP(WAKE);	    arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
560 	P_FUTEX_OP(FD);		    arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
561 	P_FUTEX_OP(REQUEUE);	    arg->mask |= SCF_VAL3|SCF_TIMEOUT;	          break;
562 	P_FUTEX_OP(CMP_REQUEUE);    arg->mask |= SCF_TIMEOUT;			  break;
563 	P_FUTEX_OP(CMP_REQUEUE_PI); arg->mask |= SCF_TIMEOUT;			  break;
564 	P_FUTEX_OP(WAKE_OP);							  break;
565 	P_FUTEX_OP(LOCK_PI);	    arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
566 	P_FUTEX_OP(UNLOCK_PI);	    arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
567 	P_FUTEX_OP(TRYLOCK_PI);	    arg->mask |= SCF_VAL3|SCF_UADDR2;		  break;
568 	P_FUTEX_OP(WAIT_BITSET);    arg->mask |= SCF_UADDR2;			  break;
569 	P_FUTEX_OP(WAKE_BITSET);    arg->mask |= SCF_UADDR2;			  break;
570 	P_FUTEX_OP(WAIT_REQUEUE_PI);						  break;
571 	default: printed = scnprintf(bf, size, "%#x", cmd);			  break;
572 	}
573 
574 	if (op & FUTEX_PRIVATE_FLAG)
575 		printed += scnprintf(bf + printed, size - printed, "|PRIV");
576 
577 	if (op & FUTEX_CLOCK_REALTIME)
578 		printed += scnprintf(bf + printed, size - printed, "|CLKRT");
579 
580 	return printed;
581 }
582 
583 #define SCA_FUTEX_OP  syscall_arg__scnprintf_futex_op
584 
585 static const char *epoll_ctl_ops[] = { "ADD", "DEL", "MOD", };
586 static DEFINE_STRARRAY_OFFSET(epoll_ctl_ops, 1);
587 
588 static const char *itimers[] = { "REAL", "VIRTUAL", "PROF", };
589 static DEFINE_STRARRAY(itimers);
590 
591 static const char *keyctl_options[] = {
592 	"GET_KEYRING_ID", "JOIN_SESSION_KEYRING", "UPDATE", "REVOKE", "CHOWN",
593 	"SETPERM", "DESCRIBE", "CLEAR", "LINK", "UNLINK", "SEARCH", "READ",
594 	"INSTANTIATE", "NEGATE", "SET_REQKEY_KEYRING", "SET_TIMEOUT",
595 	"ASSUME_AUTHORITY", "GET_SECURITY", "SESSION_TO_PARENT", "REJECT",
596 	"INSTANTIATE_IOV", "INVALIDATE", "GET_PERSISTENT",
597 };
598 static DEFINE_STRARRAY(keyctl_options);
599 
600 static const char *whences[] = { "SET", "CUR", "END",
601 #ifdef SEEK_DATA
602 "DATA",
603 #endif
604 #ifdef SEEK_HOLE
605 "HOLE",
606 #endif
607 };
608 static DEFINE_STRARRAY(whences);
609 
610 static const char *fcntl_cmds[] = {
611 	"DUPFD", "GETFD", "SETFD", "GETFL", "SETFL", "GETLK", "SETLK",
612 	"SETLKW", "SETOWN", "GETOWN", "SETSIG", "GETSIG", "F_GETLK64",
613 	"F_SETLK64", "F_SETLKW64", "F_SETOWN_EX", "F_GETOWN_EX",
614 	"F_GETOWNER_UIDS",
615 };
616 static DEFINE_STRARRAY(fcntl_cmds);
617 
618 static const char *rlimit_resources[] = {
619 	"CPU", "FSIZE", "DATA", "STACK", "CORE", "RSS", "NPROC", "NOFILE",
620 	"MEMLOCK", "AS", "LOCKS", "SIGPENDING", "MSGQUEUE", "NICE", "RTPRIO",
621 	"RTTIME",
622 };
623 static DEFINE_STRARRAY(rlimit_resources);
624 
625 static const char *sighow[] = { "BLOCK", "UNBLOCK", "SETMASK", };
626 static DEFINE_STRARRAY(sighow);
627 
628 static const char *clockid[] = {
629 	"REALTIME", "MONOTONIC", "PROCESS_CPUTIME_ID", "THREAD_CPUTIME_ID",
630 	"MONOTONIC_RAW", "REALTIME_COARSE", "MONOTONIC_COARSE", "BOOTTIME",
631 	"REALTIME_ALARM", "BOOTTIME_ALARM", "SGI_CYCLE", "TAI"
632 };
633 static DEFINE_STRARRAY(clockid);
634 
635 static const char *socket_families[] = {
636 	"UNSPEC", "LOCAL", "INET", "AX25", "IPX", "APPLETALK", "NETROM",
637 	"BRIDGE", "ATMPVC", "X25", "INET6", "ROSE", "DECnet", "NETBEUI",
638 	"SECURITY", "KEY", "NETLINK", "PACKET", "ASH", "ECONET", "ATMSVC",
639 	"RDS", "SNA", "IRDA", "PPPOX", "WANPIPE", "LLC", "IB", "CAN", "TIPC",
640 	"BLUETOOTH", "IUCV", "RXRPC", "ISDN", "PHONET", "IEEE802154", "CAIF",
641 	"ALG", "NFC", "VSOCK",
642 };
643 static DEFINE_STRARRAY(socket_families);
644 
645 #ifndef SOCK_TYPE_MASK
646 #define SOCK_TYPE_MASK 0xf
647 #endif
648 
649 static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size,
650 						      struct syscall_arg *arg)
651 {
652 	size_t printed;
653 	int type = arg->val,
654 	    flags = type & ~SOCK_TYPE_MASK;
655 
656 	type &= SOCK_TYPE_MASK;
657 	/*
658  	 * Can't use a strarray, MIPS may override for ABI reasons.
659  	 */
660 	switch (type) {
661 #define	P_SK_TYPE(n) case SOCK_##n: printed = scnprintf(bf, size, #n); break;
662 	P_SK_TYPE(STREAM);
663 	P_SK_TYPE(DGRAM);
664 	P_SK_TYPE(RAW);
665 	P_SK_TYPE(RDM);
666 	P_SK_TYPE(SEQPACKET);
667 	P_SK_TYPE(DCCP);
668 	P_SK_TYPE(PACKET);
669 #undef P_SK_TYPE
670 	default:
671 		printed = scnprintf(bf, size, "%#x", type);
672 	}
673 
674 #define	P_SK_FLAG(n) \
675 	if (flags & SOCK_##n) { \
676 		printed += scnprintf(bf + printed, size - printed, "|%s", #n); \
677 		flags &= ~SOCK_##n; \
678 	}
679 
680 	P_SK_FLAG(CLOEXEC);
681 	P_SK_FLAG(NONBLOCK);
682 #undef P_SK_FLAG
683 
684 	if (flags)
685 		printed += scnprintf(bf + printed, size - printed, "|%#x", flags);
686 
687 	return printed;
688 }
689 
690 #define SCA_SK_TYPE syscall_arg__scnprintf_socket_type
691 
692 #ifndef MSG_PROBE
693 #define MSG_PROBE	     0x10
694 #endif
695 #ifndef MSG_WAITFORONE
696 #define MSG_WAITFORONE	0x10000
697 #endif
698 #ifndef MSG_SENDPAGE_NOTLAST
699 #define MSG_SENDPAGE_NOTLAST 0x20000
700 #endif
701 #ifndef MSG_FASTOPEN
702 #define MSG_FASTOPEN	     0x20000000
703 #endif
704 
705 static size_t syscall_arg__scnprintf_msg_flags(char *bf, size_t size,
706 					       struct syscall_arg *arg)
707 {
708 	int printed = 0, flags = arg->val;
709 
710 	if (flags == 0)
711 		return scnprintf(bf, size, "NONE");
712 #define	P_MSG_FLAG(n) \
713 	if (flags & MSG_##n) { \
714 		printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
715 		flags &= ~MSG_##n; \
716 	}
717 
718 	P_MSG_FLAG(OOB);
719 	P_MSG_FLAG(PEEK);
720 	P_MSG_FLAG(DONTROUTE);
721 	P_MSG_FLAG(TRYHARD);
722 	P_MSG_FLAG(CTRUNC);
723 	P_MSG_FLAG(PROBE);
724 	P_MSG_FLAG(TRUNC);
725 	P_MSG_FLAG(DONTWAIT);
726 	P_MSG_FLAG(EOR);
727 	P_MSG_FLAG(WAITALL);
728 	P_MSG_FLAG(FIN);
729 	P_MSG_FLAG(SYN);
730 	P_MSG_FLAG(CONFIRM);
731 	P_MSG_FLAG(RST);
732 	P_MSG_FLAG(ERRQUEUE);
733 	P_MSG_FLAG(NOSIGNAL);
734 	P_MSG_FLAG(MORE);
735 	P_MSG_FLAG(WAITFORONE);
736 	P_MSG_FLAG(SENDPAGE_NOTLAST);
737 	P_MSG_FLAG(FASTOPEN);
738 	P_MSG_FLAG(CMSG_CLOEXEC);
739 #undef P_MSG_FLAG
740 
741 	if (flags)
742 		printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
743 
744 	return printed;
745 }
746 
747 #define SCA_MSG_FLAGS syscall_arg__scnprintf_msg_flags
748 
749 static size_t syscall_arg__scnprintf_access_mode(char *bf, size_t size,
750 						 struct syscall_arg *arg)
751 {
752 	size_t printed = 0;
753 	int mode = arg->val;
754 
755 	if (mode == F_OK) /* 0 */
756 		return scnprintf(bf, size, "F");
757 #define	P_MODE(n) \
758 	if (mode & n##_OK) { \
759 		printed += scnprintf(bf + printed, size - printed, "%s", #n); \
760 		mode &= ~n##_OK; \
761 	}
762 
763 	P_MODE(R);
764 	P_MODE(W);
765 	P_MODE(X);
766 #undef P_MODE
767 
768 	if (mode)
769 		printed += scnprintf(bf + printed, size - printed, "|%#x", mode);
770 
771 	return printed;
772 }
773 
774 #define SCA_ACCMODE syscall_arg__scnprintf_access_mode
775 
776 static size_t syscall_arg__scnprintf_filename(char *bf, size_t size,
777 					      struct syscall_arg *arg);
778 
779 #define SCA_FILENAME syscall_arg__scnprintf_filename
780 
781 static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size,
782 					       struct syscall_arg *arg)
783 {
784 	int printed = 0, flags = arg->val;
785 
786 	if (!(flags & O_CREAT))
787 		arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */
788 
789 	if (flags == 0)
790 		return scnprintf(bf, size, "RDONLY");
791 #define	P_FLAG(n) \
792 	if (flags & O_##n) { \
793 		printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
794 		flags &= ~O_##n; \
795 	}
796 
797 	P_FLAG(APPEND);
798 	P_FLAG(ASYNC);
799 	P_FLAG(CLOEXEC);
800 	P_FLAG(CREAT);
801 	P_FLAG(DIRECT);
802 	P_FLAG(DIRECTORY);
803 	P_FLAG(EXCL);
804 	P_FLAG(LARGEFILE);
805 	P_FLAG(NOATIME);
806 	P_FLAG(NOCTTY);
807 #ifdef O_NONBLOCK
808 	P_FLAG(NONBLOCK);
809 #elif O_NDELAY
810 	P_FLAG(NDELAY);
811 #endif
812 #ifdef O_PATH
813 	P_FLAG(PATH);
814 #endif
815 	P_FLAG(RDWR);
816 #ifdef O_DSYNC
817 	if ((flags & O_SYNC) == O_SYNC)
818 		printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", "SYNC");
819 	else {
820 		P_FLAG(DSYNC);
821 	}
822 #else
823 	P_FLAG(SYNC);
824 #endif
825 	P_FLAG(TRUNC);
826 	P_FLAG(WRONLY);
827 #undef P_FLAG
828 
829 	if (flags)
830 		printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
831 
832 	return printed;
833 }
834 
835 #define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags
836 
837 static size_t syscall_arg__scnprintf_perf_flags(char *bf, size_t size,
838 						struct syscall_arg *arg)
839 {
840 	int printed = 0, flags = arg->val;
841 
842 	if (flags == 0)
843 		return 0;
844 
845 #define	P_FLAG(n) \
846 	if (flags & PERF_FLAG_##n) { \
847 		printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
848 		flags &= ~PERF_FLAG_##n; \
849 	}
850 
851 	P_FLAG(FD_NO_GROUP);
852 	P_FLAG(FD_OUTPUT);
853 	P_FLAG(PID_CGROUP);
854 	P_FLAG(FD_CLOEXEC);
855 #undef P_FLAG
856 
857 	if (flags)
858 		printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
859 
860 	return printed;
861 }
862 
863 #define SCA_PERF_FLAGS syscall_arg__scnprintf_perf_flags
864 
865 static size_t syscall_arg__scnprintf_eventfd_flags(char *bf, size_t size,
866 						   struct syscall_arg *arg)
867 {
868 	int printed = 0, flags = arg->val;
869 
870 	if (flags == 0)
871 		return scnprintf(bf, size, "NONE");
872 #define	P_FLAG(n) \
873 	if (flags & EFD_##n) { \
874 		printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
875 		flags &= ~EFD_##n; \
876 	}
877 
878 	P_FLAG(SEMAPHORE);
879 	P_FLAG(CLOEXEC);
880 	P_FLAG(NONBLOCK);
881 #undef P_FLAG
882 
883 	if (flags)
884 		printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
885 
886 	return printed;
887 }
888 
889 #define SCA_EFD_FLAGS syscall_arg__scnprintf_eventfd_flags
890 
891 static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size,
892 						struct syscall_arg *arg)
893 {
894 	int printed = 0, flags = arg->val;
895 
896 #define	P_FLAG(n) \
897 	if (flags & O_##n) { \
898 		printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
899 		flags &= ~O_##n; \
900 	}
901 
902 	P_FLAG(CLOEXEC);
903 	P_FLAG(NONBLOCK);
904 #undef P_FLAG
905 
906 	if (flags)
907 		printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
908 
909 	return printed;
910 }
911 
912 #define SCA_PIPE_FLAGS syscall_arg__scnprintf_pipe_flags
913 
914 static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg)
915 {
916 	int sig = arg->val;
917 
918 	switch (sig) {
919 #define	P_SIGNUM(n) case SIG##n: return scnprintf(bf, size, #n)
920 	P_SIGNUM(HUP);
921 	P_SIGNUM(INT);
922 	P_SIGNUM(QUIT);
923 	P_SIGNUM(ILL);
924 	P_SIGNUM(TRAP);
925 	P_SIGNUM(ABRT);
926 	P_SIGNUM(BUS);
927 	P_SIGNUM(FPE);
928 	P_SIGNUM(KILL);
929 	P_SIGNUM(USR1);
930 	P_SIGNUM(SEGV);
931 	P_SIGNUM(USR2);
932 	P_SIGNUM(PIPE);
933 	P_SIGNUM(ALRM);
934 	P_SIGNUM(TERM);
935 	P_SIGNUM(CHLD);
936 	P_SIGNUM(CONT);
937 	P_SIGNUM(STOP);
938 	P_SIGNUM(TSTP);
939 	P_SIGNUM(TTIN);
940 	P_SIGNUM(TTOU);
941 	P_SIGNUM(URG);
942 	P_SIGNUM(XCPU);
943 	P_SIGNUM(XFSZ);
944 	P_SIGNUM(VTALRM);
945 	P_SIGNUM(PROF);
946 	P_SIGNUM(WINCH);
947 	P_SIGNUM(IO);
948 	P_SIGNUM(PWR);
949 	P_SIGNUM(SYS);
950 #ifdef SIGEMT
951 	P_SIGNUM(EMT);
952 #endif
953 #ifdef SIGSTKFLT
954 	P_SIGNUM(STKFLT);
955 #endif
956 #ifdef SIGSWI
957 	P_SIGNUM(SWI);
958 #endif
959 	default: break;
960 	}
961 
962 	return scnprintf(bf, size, "%#x", sig);
963 }
964 
965 #define SCA_SIGNUM syscall_arg__scnprintf_signum
966 
967 #if defined(__i386__) || defined(__x86_64__)
968 /*
969  * FIXME: Make this available to all arches.
970  */
971 #define TCGETS		0x5401
972 
973 static const char *tioctls[] = {
974 	"TCGETS", "TCSETS", "TCSETSW", "TCSETSF", "TCGETA", "TCSETA", "TCSETAW",
975 	"TCSETAF", "TCSBRK", "TCXONC", "TCFLSH", "TIOCEXCL", "TIOCNXCL",
976 	"TIOCSCTTY", "TIOCGPGRP", "TIOCSPGRP", "TIOCOUTQ", "TIOCSTI",
977 	"TIOCGWINSZ", "TIOCSWINSZ", "TIOCMGET", "TIOCMBIS", "TIOCMBIC",
978 	"TIOCMSET", "TIOCGSOFTCAR", "TIOCSSOFTCAR", "FIONREAD", "TIOCLINUX",
979 	"TIOCCONS", "TIOCGSERIAL", "TIOCSSERIAL", "TIOCPKT", "FIONBIO",
980 	"TIOCNOTTY", "TIOCSETD", "TIOCGETD", "TCSBRKP", [0x27] = "TIOCSBRK",
981 	"TIOCCBRK", "TIOCGSID", "TCGETS2", "TCSETS2", "TCSETSW2", "TCSETSF2",
982 	"TIOCGRS485", "TIOCSRS485", "TIOCGPTN", "TIOCSPTLCK",
983 	"TIOCGDEV||TCGETX", "TCSETX", "TCSETXF", "TCSETXW", "TIOCSIG",
984 	"TIOCVHANGUP", "TIOCGPKT", "TIOCGPTLCK", "TIOCGEXCL",
985 	[0x50] = "FIONCLEX", "FIOCLEX", "FIOASYNC", "TIOCSERCONFIG",
986 	"TIOCSERGWILD", "TIOCSERSWILD", "TIOCGLCKTRMIOS", "TIOCSLCKTRMIOS",
987 	"TIOCSERGSTRUCT", "TIOCSERGETLSR", "TIOCSERGETMULTI", "TIOCSERSETMULTI",
988 	"TIOCMIWAIT", "TIOCGICOUNT", [0x60] = "FIOQSIZE",
989 };
990 
991 static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401);
992 #endif /* defined(__i386__) || defined(__x86_64__) */
993 
994 #define STRARRAY(arg, name, array) \
995 	  .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \
996 	  .arg_parm	 = { [arg] = &strarray__##array, }
997 
998 static struct syscall_fmt {
999 	const char *name;
1000 	const char *alias;
1001 	size_t	   (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg);
1002 	void	   *arg_parm[6];
1003 	bool	   errmsg;
1004 	bool	   timeout;
1005 	bool	   hexret;
1006 } syscall_fmts[] = {
1007 	{ .name	    = "access",	    .errmsg = true,
1008 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */
1009 			     [1] = SCA_ACCMODE,  /* mode */ }, },
1010 	{ .name	    = "arch_prctl", .errmsg = true, .alias = "prctl", },
1011 	{ .name	    = "brk",	    .hexret = true,
1012 	  .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, },
1013 	{ .name	    = "chdir",	    .errmsg = true,
1014 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1015 	{ .name	    = "chmod",	    .errmsg = true,
1016 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1017 	{ .name	    = "chroot",	    .errmsg = true,
1018 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1019 	{ .name     = "clock_gettime",  .errmsg = true, STRARRAY(0, clk_id, clockid), },
1020 	{ .name	    = "close",	    .errmsg = true,
1021 	  .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, },
1022 	{ .name	    = "connect",    .errmsg = true, },
1023 	{ .name	    = "creat",	    .errmsg = true,
1024 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1025 	{ .name	    = "dup",	    .errmsg = true,
1026 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1027 	{ .name	    = "dup2",	    .errmsg = true,
1028 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1029 	{ .name	    = "dup3",	    .errmsg = true,
1030 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1031 	{ .name	    = "epoll_ctl",  .errmsg = true, STRARRAY(1, op, epoll_ctl_ops), },
1032 	{ .name	    = "eventfd2",   .errmsg = true,
1033 	  .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, },
1034 	{ .name	    = "faccessat",  .errmsg = true,
1035 	  .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1036 			     [1] = SCA_FILENAME, /* filename */ }, },
1037 	{ .name	    = "fadvise64",  .errmsg = true,
1038 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1039 	{ .name	    = "fallocate",  .errmsg = true,
1040 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1041 	{ .name	    = "fchdir",	    .errmsg = true,
1042 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1043 	{ .name	    = "fchmod",	    .errmsg = true,
1044 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1045 	{ .name	    = "fchmodat",   .errmsg = true,
1046 	  .arg_scnprintf = { [0] = SCA_FDAT, /* fd */
1047 			     [1] = SCA_FILENAME, /* filename */ }, },
1048 	{ .name	    = "fchown",	    .errmsg = true,
1049 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1050 	{ .name	    = "fchownat",   .errmsg = true,
1051 	  .arg_scnprintf = { [0] = SCA_FDAT, /* fd */
1052 			     [1] = SCA_FILENAME, /* filename */ }, },
1053 	{ .name	    = "fcntl",	    .errmsg = true,
1054 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */
1055 			     [1] = SCA_STRARRAY, /* cmd */ },
1056 	  .arg_parm	 = { [1] = &strarray__fcntl_cmds, /* cmd */ }, },
1057 	{ .name	    = "fdatasync",  .errmsg = true,
1058 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1059 	{ .name	    = "flock",	    .errmsg = true,
1060 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */
1061 			     [1] = SCA_FLOCK, /* cmd */ }, },
1062 	{ .name	    = "fsetxattr",  .errmsg = true,
1063 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1064 	{ .name	    = "fstat",	    .errmsg = true, .alias = "newfstat",
1065 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1066 	{ .name	    = "fstatat",    .errmsg = true, .alias = "newfstatat",
1067 	  .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1068 			     [1] = SCA_FILENAME, /* filename */ }, },
1069 	{ .name	    = "fstatfs",    .errmsg = true,
1070 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1071 	{ .name	    = "fsync",    .errmsg = true,
1072 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1073 	{ .name	    = "ftruncate", .errmsg = true,
1074 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1075 	{ .name	    = "futex",	    .errmsg = true,
1076 	  .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, },
1077 	{ .name	    = "futimesat", .errmsg = true,
1078 	  .arg_scnprintf = { [0] = SCA_FDAT, /* fd */
1079 			     [1] = SCA_FILENAME, /* filename */ }, },
1080 	{ .name	    = "getdents",   .errmsg = true,
1081 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1082 	{ .name	    = "getdents64", .errmsg = true,
1083 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1084 	{ .name	    = "getitimer",  .errmsg = true, STRARRAY(0, which, itimers), },
1085 	{ .name	    = "getrlimit",  .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
1086 	{ .name	    = "getxattr",    .errmsg = true,
1087 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1088 	{ .name	    = "inotify_add_watch",	    .errmsg = true,
1089 	  .arg_scnprintf = { [1] = SCA_FILENAME, /* pathname */ }, },
1090 	{ .name	    = "ioctl",	    .errmsg = true,
1091 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */
1092 #if defined(__i386__) || defined(__x86_64__)
1093 /*
1094  * FIXME: Make this available to all arches.
1095  */
1096 			     [1] = SCA_STRHEXARRAY, /* cmd */
1097 			     [2] = SCA_HEX, /* arg */ },
1098 	  .arg_parm	 = { [1] = &strarray__tioctls, /* cmd */ }, },
1099 #else
1100 			     [2] = SCA_HEX, /* arg */ }, },
1101 #endif
1102 	{ .name	    = "keyctl",	    .errmsg = true, STRARRAY(0, option, keyctl_options), },
1103 	{ .name	    = "kill",	    .errmsg = true,
1104 	  .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
1105 	{ .name	    = "lchown",    .errmsg = true,
1106 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1107 	{ .name	    = "lgetxattr",  .errmsg = true,
1108 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1109 	{ .name	    = "linkat",	    .errmsg = true,
1110 	  .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, },
1111 	{ .name	    = "listxattr",  .errmsg = true,
1112 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1113 	{ .name	    = "llistxattr", .errmsg = true,
1114 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1115 	{ .name	    = "lremovexattr",  .errmsg = true,
1116 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1117 	{ .name	    = "lseek",	    .errmsg = true,
1118 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */
1119 			     [2] = SCA_STRARRAY, /* whence */ },
1120 	  .arg_parm	 = { [2] = &strarray__whences, /* whence */ }, },
1121 	{ .name	    = "lsetxattr",  .errmsg = true,
1122 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1123 	{ .name	    = "lstat",	    .errmsg = true, .alias = "newlstat",
1124 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1125 	{ .name	    = "lsxattr",    .errmsg = true,
1126 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1127 	{ .name     = "madvise",    .errmsg = true,
1128 	  .arg_scnprintf = { [0] = SCA_HEX,	 /* start */
1129 			     [2] = SCA_MADV_BHV, /* behavior */ }, },
1130 	{ .name	    = "mkdir",    .errmsg = true,
1131 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1132 	{ .name	    = "mkdirat",    .errmsg = true,
1133 	  .arg_scnprintf = { [0] = SCA_FDAT, /* fd */
1134 			     [1] = SCA_FILENAME, /* pathname */ }, },
1135 	{ .name	    = "mknod",      .errmsg = true,
1136 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1137 	{ .name	    = "mknodat",    .errmsg = true,
1138 	  .arg_scnprintf = { [0] = SCA_FDAT, /* fd */
1139 			     [1] = SCA_FILENAME, /* filename */ }, },
1140 	{ .name	    = "mlock",	    .errmsg = true,
1141 	  .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
1142 	{ .name	    = "mlockall",   .errmsg = true,
1143 	  .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
1144 	{ .name	    = "mmap",	    .hexret = true,
1145 	  .arg_scnprintf = { [0] = SCA_HEX,	  /* addr */
1146 			     [2] = SCA_MMAP_PROT, /* prot */
1147 			     [3] = SCA_MMAP_FLAGS, /* flags */
1148 			     [4] = SCA_FD, 	  /* fd */ }, },
1149 	{ .name	    = "mprotect",   .errmsg = true,
1150 	  .arg_scnprintf = { [0] = SCA_HEX, /* start */
1151 			     [2] = SCA_MMAP_PROT, /* prot */ }, },
1152 	{ .name	    = "mq_unlink", .errmsg = true,
1153 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* u_name */ }, },
1154 	{ .name	    = "mremap",	    .hexret = true,
1155 	  .arg_scnprintf = { [0] = SCA_HEX, /* addr */
1156 			     [3] = SCA_MREMAP_FLAGS, /* flags */
1157 			     [4] = SCA_HEX, /* new_addr */ }, },
1158 	{ .name	    = "munlock",    .errmsg = true,
1159 	  .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
1160 	{ .name	    = "munmap",	    .errmsg = true,
1161 	  .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
1162 	{ .name	    = "name_to_handle_at", .errmsg = true,
1163 	  .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
1164 	{ .name	    = "newfstatat", .errmsg = true,
1165 	  .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1166 			     [1] = SCA_FILENAME, /* filename */ }, },
1167 	{ .name	    = "open",	    .errmsg = true,
1168 	  .arg_scnprintf = { [0] = SCA_FILENAME,   /* filename */
1169 			     [1] = SCA_OPEN_FLAGS, /* flags */ }, },
1170 	{ .name	    = "open_by_handle_at", .errmsg = true,
1171 	  .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1172 			     [2] = SCA_OPEN_FLAGS, /* flags */ }, },
1173 	{ .name	    = "openat",	    .errmsg = true,
1174 	  .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1175 			     [1] = SCA_FILENAME, /* filename */
1176 			     [2] = SCA_OPEN_FLAGS, /* flags */ }, },
1177 	{ .name	    = "perf_event_open", .errmsg = true,
1178 	  .arg_scnprintf = { [1] = SCA_INT, /* pid */
1179 			     [2] = SCA_INT, /* cpu */
1180 			     [3] = SCA_FD,  /* group_fd */
1181 			     [4] = SCA_PERF_FLAGS,  /* flags */ }, },
1182 	{ .name	    = "pipe2",	    .errmsg = true,
1183 	  .arg_scnprintf = { [1] = SCA_PIPE_FLAGS, /* flags */ }, },
1184 	{ .name	    = "poll",	    .errmsg = true, .timeout = true, },
1185 	{ .name	    = "ppoll",	    .errmsg = true, .timeout = true, },
1186 	{ .name	    = "pread",	    .errmsg = true, .alias = "pread64",
1187 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1188 	{ .name	    = "preadv",	    .errmsg = true, .alias = "pread",
1189 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1190 	{ .name	    = "prlimit64",  .errmsg = true, STRARRAY(1, resource, rlimit_resources), },
1191 	{ .name	    = "pwrite",	    .errmsg = true, .alias = "pwrite64",
1192 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1193 	{ .name	    = "pwritev",    .errmsg = true,
1194 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1195 	{ .name	    = "read",	    .errmsg = true,
1196 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1197 	{ .name	    = "readlink",   .errmsg = true,
1198 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* path */ }, },
1199 	{ .name	    = "readlinkat", .errmsg = true,
1200 	  .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1201 			     [1] = SCA_FILENAME, /* pathname */ }, },
1202 	{ .name	    = "readv",	    .errmsg = true,
1203 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1204 	{ .name	    = "recvfrom",   .errmsg = true,
1205 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */
1206 			     [3] = SCA_MSG_FLAGS, /* flags */ }, },
1207 	{ .name	    = "recvmmsg",   .errmsg = true,
1208 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */
1209 			     [3] = SCA_MSG_FLAGS, /* flags */ }, },
1210 	{ .name	    = "recvmsg",    .errmsg = true,
1211 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */
1212 			     [2] = SCA_MSG_FLAGS, /* flags */ }, },
1213 	{ .name	    = "removexattr", .errmsg = true,
1214 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1215 	{ .name	    = "renameat",   .errmsg = true,
1216 	  .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
1217 	{ .name	    = "rmdir",    .errmsg = true,
1218 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1219 	{ .name	    = "rt_sigaction", .errmsg = true,
1220 	  .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, },
1221 	{ .name	    = "rt_sigprocmask",  .errmsg = true, STRARRAY(0, how, sighow), },
1222 	{ .name	    = "rt_sigqueueinfo", .errmsg = true,
1223 	  .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
1224 	{ .name	    = "rt_tgsigqueueinfo", .errmsg = true,
1225 	  .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, },
1226 	{ .name	    = "select",	    .errmsg = true, .timeout = true, },
1227 	{ .name	    = "sendmmsg",    .errmsg = true,
1228 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */
1229 			     [3] = SCA_MSG_FLAGS, /* flags */ }, },
1230 	{ .name	    = "sendmsg",    .errmsg = true,
1231 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */
1232 			     [2] = SCA_MSG_FLAGS, /* flags */ }, },
1233 	{ .name	    = "sendto",	    .errmsg = true,
1234 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */
1235 			     [3] = SCA_MSG_FLAGS, /* flags */ }, },
1236 	{ .name	    = "setitimer",  .errmsg = true, STRARRAY(0, which, itimers), },
1237 	{ .name	    = "setrlimit",  .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
1238 	{ .name	    = "setxattr",   .errmsg = true,
1239 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1240 	{ .name	    = "shutdown",   .errmsg = true,
1241 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1242 	{ .name	    = "socket",	    .errmsg = true,
1243 	  .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */
1244 			     [1] = SCA_SK_TYPE, /* type */ },
1245 	  .arg_parm	 = { [0] = &strarray__socket_families, /* family */ }, },
1246 	{ .name	    = "socketpair", .errmsg = true,
1247 	  .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */
1248 			     [1] = SCA_SK_TYPE, /* type */ },
1249 	  .arg_parm	 = { [0] = &strarray__socket_families, /* family */ }, },
1250 	{ .name	    = "stat",	    .errmsg = true, .alias = "newstat",
1251 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1252 	{ .name	    = "statfs",	    .errmsg = true,
1253 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1254 	{ .name	    = "swapoff",    .errmsg = true,
1255 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* specialfile */ }, },
1256 	{ .name	    = "swapon",	    .errmsg = true,
1257 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* specialfile */ }, },
1258 	{ .name	    = "symlinkat",  .errmsg = true,
1259 	  .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
1260 	{ .name	    = "tgkill",	    .errmsg = true,
1261 	  .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, },
1262 	{ .name	    = "tkill",	    .errmsg = true,
1263 	  .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
1264 	{ .name	    = "truncate",   .errmsg = true,
1265 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* path */ }, },
1266 	{ .name	    = "uname",	    .errmsg = true, .alias = "newuname", },
1267 	{ .name	    = "unlinkat",   .errmsg = true,
1268 	  .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1269 			     [1] = SCA_FILENAME, /* pathname */ }, },
1270 	{ .name	    = "utime",  .errmsg = true,
1271 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1272 	{ .name	    = "utimensat",  .errmsg = true,
1273 	  .arg_scnprintf = { [0] = SCA_FDAT, /* dirfd */
1274 			     [1] = SCA_FILENAME, /* filename */ }, },
1275 	{ .name	    = "utimes",  .errmsg = true,
1276 	  .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1277 	{ .name	    = "vmsplice",  .errmsg = true,
1278 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1279 	{ .name	    = "write",	    .errmsg = true,
1280 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1281 	{ .name	    = "writev",	    .errmsg = true,
1282 	  .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1283 };
1284 
1285 static int syscall_fmt__cmp(const void *name, const void *fmtp)
1286 {
1287 	const struct syscall_fmt *fmt = fmtp;
1288 	return strcmp(name, fmt->name);
1289 }
1290 
1291 static struct syscall_fmt *syscall_fmt__find(const char *name)
1292 {
1293 	const int nmemb = ARRAY_SIZE(syscall_fmts);
1294 	return bsearch(name, syscall_fmts, nmemb, sizeof(struct syscall_fmt), syscall_fmt__cmp);
1295 }
1296 
1297 struct syscall {
1298 	struct event_format *tp_format;
1299 	int		    nr_args;
1300 	struct format_field *args;
1301 	const char	    *name;
1302 	bool		    is_exit;
1303 	struct syscall_fmt  *fmt;
1304 	size_t		    (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg);
1305 	void		    **arg_parm;
1306 };
1307 
1308 static size_t fprintf_duration(unsigned long t, FILE *fp)
1309 {
1310 	double duration = (double)t / NSEC_PER_MSEC;
1311 	size_t printed = fprintf(fp, "(");
1312 
1313 	if (duration >= 1.0)
1314 		printed += color_fprintf(fp, PERF_COLOR_RED, "%6.3f ms", duration);
1315 	else if (duration >= 0.01)
1316 		printed += color_fprintf(fp, PERF_COLOR_YELLOW, "%6.3f ms", duration);
1317 	else
1318 		printed += color_fprintf(fp, PERF_COLOR_NORMAL, "%6.3f ms", duration);
1319 	return printed + fprintf(fp, "): ");
1320 }
1321 
1322 /**
1323  * filename.ptr: The filename char pointer that will be vfs_getname'd
1324  * filename.entry_str_pos: Where to insert the string translated from
1325  *                         filename.ptr by the vfs_getname tracepoint/kprobe.
1326  */
1327 struct thread_trace {
1328 	u64		  entry_time;
1329 	u64		  exit_time;
1330 	bool		  entry_pending;
1331 	unsigned long	  nr_events;
1332 	unsigned long	  pfmaj, pfmin;
1333 	char		  *entry_str;
1334 	double		  runtime_ms;
1335         struct {
1336 		unsigned long ptr;
1337 		short int     entry_str_pos;
1338 		bool	      pending_open;
1339 		unsigned int  namelen;
1340 		char	      *name;
1341 	} filename;
1342 	struct {
1343 		int	  max;
1344 		char	  **table;
1345 	} paths;
1346 
1347 	struct intlist *syscall_stats;
1348 };
1349 
1350 static struct thread_trace *thread_trace__new(void)
1351 {
1352 	struct thread_trace *ttrace =  zalloc(sizeof(struct thread_trace));
1353 
1354 	if (ttrace)
1355 		ttrace->paths.max = -1;
1356 
1357 	ttrace->syscall_stats = intlist__new(NULL);
1358 
1359 	return ttrace;
1360 }
1361 
1362 static struct thread_trace *thread__trace(struct thread *thread, FILE *fp)
1363 {
1364 	struct thread_trace *ttrace;
1365 
1366 	if (thread == NULL)
1367 		goto fail;
1368 
1369 	if (thread__priv(thread) == NULL)
1370 		thread__set_priv(thread, thread_trace__new());
1371 
1372 	if (thread__priv(thread) == NULL)
1373 		goto fail;
1374 
1375 	ttrace = thread__priv(thread);
1376 	++ttrace->nr_events;
1377 
1378 	return ttrace;
1379 fail:
1380 	color_fprintf(fp, PERF_COLOR_RED,
1381 		      "WARNING: not enough memory, dropping samples!\n");
1382 	return NULL;
1383 }
1384 
1385 #define TRACE_PFMAJ		(1 << 0)
1386 #define TRACE_PFMIN		(1 << 1)
1387 
1388 static const size_t trace__entry_str_size = 2048;
1389 
1390 struct trace {
1391 	struct perf_tool	tool;
1392 	struct {
1393 		int		machine;
1394 		int		open_id;
1395 	}			audit;
1396 	struct {
1397 		int		max;
1398 		struct syscall  *table;
1399 		struct {
1400 			struct perf_evsel *sys_enter,
1401 					  *sys_exit;
1402 		}		events;
1403 	} syscalls;
1404 	struct record_opts	opts;
1405 	struct perf_evlist	*evlist;
1406 	struct machine		*host;
1407 	struct thread		*current;
1408 	u64			base_time;
1409 	FILE			*output;
1410 	unsigned long		nr_events;
1411 	struct strlist		*ev_qualifier;
1412 	struct {
1413 		size_t		nr;
1414 		int		*entries;
1415 	}			ev_qualifier_ids;
1416 	struct intlist		*tid_list;
1417 	struct intlist		*pid_list;
1418 	struct {
1419 		size_t		nr;
1420 		pid_t		*entries;
1421 	}			filter_pids;
1422 	double			duration_filter;
1423 	double			runtime_ms;
1424 	struct {
1425 		u64		vfs_getname,
1426 				proc_getname;
1427 	} stats;
1428 	bool			not_ev_qualifier;
1429 	bool			live;
1430 	bool			full_time;
1431 	bool			sched;
1432 	bool			multiple_threads;
1433 	bool			summary;
1434 	bool			summary_only;
1435 	bool			show_comm;
1436 	bool			show_tool_stats;
1437 	bool			trace_syscalls;
1438 	bool			force;
1439 	bool			vfs_getname;
1440 	int			trace_pgfaults;
1441 };
1442 
1443 static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname)
1444 {
1445 	struct thread_trace *ttrace = thread__priv(thread);
1446 
1447 	if (fd > ttrace->paths.max) {
1448 		char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *));
1449 
1450 		if (npath == NULL)
1451 			return -1;
1452 
1453 		if (ttrace->paths.max != -1) {
1454 			memset(npath + ttrace->paths.max + 1, 0,
1455 			       (fd - ttrace->paths.max) * sizeof(char *));
1456 		} else {
1457 			memset(npath, 0, (fd + 1) * sizeof(char *));
1458 		}
1459 
1460 		ttrace->paths.table = npath;
1461 		ttrace->paths.max   = fd;
1462 	}
1463 
1464 	ttrace->paths.table[fd] = strdup(pathname);
1465 
1466 	return ttrace->paths.table[fd] != NULL ? 0 : -1;
1467 }
1468 
1469 static int thread__read_fd_path(struct thread *thread, int fd)
1470 {
1471 	char linkname[PATH_MAX], pathname[PATH_MAX];
1472 	struct stat st;
1473 	int ret;
1474 
1475 	if (thread->pid_ == thread->tid) {
1476 		scnprintf(linkname, sizeof(linkname),
1477 			  "/proc/%d/fd/%d", thread->pid_, fd);
1478 	} else {
1479 		scnprintf(linkname, sizeof(linkname),
1480 			  "/proc/%d/task/%d/fd/%d", thread->pid_, thread->tid, fd);
1481 	}
1482 
1483 	if (lstat(linkname, &st) < 0 || st.st_size + 1 > (off_t)sizeof(pathname))
1484 		return -1;
1485 
1486 	ret = readlink(linkname, pathname, sizeof(pathname));
1487 
1488 	if (ret < 0 || ret > st.st_size)
1489 		return -1;
1490 
1491 	pathname[ret] = '\0';
1492 	return trace__set_fd_pathname(thread, fd, pathname);
1493 }
1494 
1495 static const char *thread__fd_path(struct thread *thread, int fd,
1496 				   struct trace *trace)
1497 {
1498 	struct thread_trace *ttrace = thread__priv(thread);
1499 
1500 	if (ttrace == NULL)
1501 		return NULL;
1502 
1503 	if (fd < 0)
1504 		return NULL;
1505 
1506 	if ((fd > ttrace->paths.max || ttrace->paths.table[fd] == NULL)) {
1507 		if (!trace->live)
1508 			return NULL;
1509 		++trace->stats.proc_getname;
1510 		if (thread__read_fd_path(thread, fd))
1511 			return NULL;
1512 	}
1513 
1514 	return ttrace->paths.table[fd];
1515 }
1516 
1517 static size_t syscall_arg__scnprintf_fd(char *bf, size_t size,
1518 					struct syscall_arg *arg)
1519 {
1520 	int fd = arg->val;
1521 	size_t printed = scnprintf(bf, size, "%d", fd);
1522 	const char *path = thread__fd_path(arg->thread, fd, arg->trace);
1523 
1524 	if (path)
1525 		printed += scnprintf(bf + printed, size - printed, "<%s>", path);
1526 
1527 	return printed;
1528 }
1529 
1530 static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size,
1531 					      struct syscall_arg *arg)
1532 {
1533 	int fd = arg->val;
1534 	size_t printed = syscall_arg__scnprintf_fd(bf, size, arg);
1535 	struct thread_trace *ttrace = thread__priv(arg->thread);
1536 
1537 	if (ttrace && fd >= 0 && fd <= ttrace->paths.max)
1538 		zfree(&ttrace->paths.table[fd]);
1539 
1540 	return printed;
1541 }
1542 
1543 static void thread__set_filename_pos(struct thread *thread, const char *bf,
1544 				     unsigned long ptr)
1545 {
1546 	struct thread_trace *ttrace = thread__priv(thread);
1547 
1548 	ttrace->filename.ptr = ptr;
1549 	ttrace->filename.entry_str_pos = bf - ttrace->entry_str;
1550 }
1551 
1552 static size_t syscall_arg__scnprintf_filename(char *bf, size_t size,
1553 					      struct syscall_arg *arg)
1554 {
1555 	unsigned long ptr = arg->val;
1556 
1557 	if (!arg->trace->vfs_getname)
1558 		return scnprintf(bf, size, "%#x", ptr);
1559 
1560 	thread__set_filename_pos(arg->thread, bf, ptr);
1561 	return 0;
1562 }
1563 
1564 static bool trace__filter_duration(struct trace *trace, double t)
1565 {
1566 	return t < (trace->duration_filter * NSEC_PER_MSEC);
1567 }
1568 
1569 static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp)
1570 {
1571 	double ts = (double)(tstamp - trace->base_time) / NSEC_PER_MSEC;
1572 
1573 	return fprintf(fp, "%10.3f ", ts);
1574 }
1575 
1576 static bool done = false;
1577 static bool interrupted = false;
1578 
1579 static void sig_handler(int sig)
1580 {
1581 	done = true;
1582 	interrupted = sig == SIGINT;
1583 }
1584 
1585 static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thread,
1586 					u64 duration, u64 tstamp, FILE *fp)
1587 {
1588 	size_t printed = trace__fprintf_tstamp(trace, tstamp, fp);
1589 	printed += fprintf_duration(duration, fp);
1590 
1591 	if (trace->multiple_threads) {
1592 		if (trace->show_comm)
1593 			printed += fprintf(fp, "%.14s/", thread__comm_str(thread));
1594 		printed += fprintf(fp, "%d ", thread->tid);
1595 	}
1596 
1597 	return printed;
1598 }
1599 
1600 static int trace__process_event(struct trace *trace, struct machine *machine,
1601 				union perf_event *event, struct perf_sample *sample)
1602 {
1603 	int ret = 0;
1604 
1605 	switch (event->header.type) {
1606 	case PERF_RECORD_LOST:
1607 		color_fprintf(trace->output, PERF_COLOR_RED,
1608 			      "LOST %" PRIu64 " events!\n", event->lost.lost);
1609 		ret = machine__process_lost_event(machine, event, sample);
1610 	default:
1611 		ret = machine__process_event(machine, event, sample);
1612 		break;
1613 	}
1614 
1615 	return ret;
1616 }
1617 
1618 static int trace__tool_process(struct perf_tool *tool,
1619 			       union perf_event *event,
1620 			       struct perf_sample *sample,
1621 			       struct machine *machine)
1622 {
1623 	struct trace *trace = container_of(tool, struct trace, tool);
1624 	return trace__process_event(trace, machine, event, sample);
1625 }
1626 
1627 static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
1628 {
1629 	int err = symbol__init(NULL);
1630 
1631 	if (err)
1632 		return err;
1633 
1634 	trace->host = machine__new_host();
1635 	if (trace->host == NULL)
1636 		return -ENOMEM;
1637 
1638 	if (trace_event__register_resolver(trace->host, machine__resolve_kernel_addr) < 0)
1639 		return -errno;
1640 
1641 	err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target,
1642 					    evlist->threads, trace__tool_process, false,
1643 					    trace->opts.proc_map_timeout);
1644 	if (err)
1645 		symbol__exit();
1646 
1647 	return err;
1648 }
1649 
1650 static int syscall__set_arg_fmts(struct syscall *sc)
1651 {
1652 	struct format_field *field;
1653 	int idx = 0;
1654 
1655 	sc->arg_scnprintf = calloc(sc->nr_args, sizeof(void *));
1656 	if (sc->arg_scnprintf == NULL)
1657 		return -1;
1658 
1659 	if (sc->fmt)
1660 		sc->arg_parm = sc->fmt->arg_parm;
1661 
1662 	for (field = sc->args; field; field = field->next) {
1663 		if (sc->fmt && sc->fmt->arg_scnprintf[idx])
1664 			sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx];
1665 		else if (field->flags & FIELD_IS_POINTER)
1666 			sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex;
1667 		++idx;
1668 	}
1669 
1670 	return 0;
1671 }
1672 
1673 static int trace__read_syscall_info(struct trace *trace, int id)
1674 {
1675 	char tp_name[128];
1676 	struct syscall *sc;
1677 	const char *name = audit_syscall_to_name(id, trace->audit.machine);
1678 
1679 	if (name == NULL)
1680 		return -1;
1681 
1682 	if (id > trace->syscalls.max) {
1683 		struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc));
1684 
1685 		if (nsyscalls == NULL)
1686 			return -1;
1687 
1688 		if (trace->syscalls.max != -1) {
1689 			memset(nsyscalls + trace->syscalls.max + 1, 0,
1690 			       (id - trace->syscalls.max) * sizeof(*sc));
1691 		} else {
1692 			memset(nsyscalls, 0, (id + 1) * sizeof(*sc));
1693 		}
1694 
1695 		trace->syscalls.table = nsyscalls;
1696 		trace->syscalls.max   = id;
1697 	}
1698 
1699 	sc = trace->syscalls.table + id;
1700 	sc->name = name;
1701 
1702 	sc->fmt  = syscall_fmt__find(sc->name);
1703 
1704 	snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name);
1705 	sc->tp_format = trace_event__tp_format("syscalls", tp_name);
1706 
1707 	if (sc->tp_format == NULL && sc->fmt && sc->fmt->alias) {
1708 		snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->fmt->alias);
1709 		sc->tp_format = trace_event__tp_format("syscalls", tp_name);
1710 	}
1711 
1712 	if (sc->tp_format == NULL)
1713 		return -1;
1714 
1715 	sc->args = sc->tp_format->format.fields;
1716 	sc->nr_args = sc->tp_format->format.nr_fields;
1717 	/* drop nr field - not relevant here; does not exist on older kernels */
1718 	if (sc->args && strcmp(sc->args->name, "nr") == 0) {
1719 		sc->args = sc->args->next;
1720 		--sc->nr_args;
1721 	}
1722 
1723 	sc->is_exit = !strcmp(name, "exit_group") || !strcmp(name, "exit");
1724 
1725 	return syscall__set_arg_fmts(sc);
1726 }
1727 
1728 static int trace__validate_ev_qualifier(struct trace *trace)
1729 {
1730 	int err = 0, i;
1731 	struct str_node *pos;
1732 
1733 	trace->ev_qualifier_ids.nr = strlist__nr_entries(trace->ev_qualifier);
1734 	trace->ev_qualifier_ids.entries = malloc(trace->ev_qualifier_ids.nr *
1735 						 sizeof(trace->ev_qualifier_ids.entries[0]));
1736 
1737 	if (trace->ev_qualifier_ids.entries == NULL) {
1738 		fputs("Error:\tNot enough memory for allocating events qualifier ids\n",
1739 		       trace->output);
1740 		err = -EINVAL;
1741 		goto out;
1742 	}
1743 
1744 	i = 0;
1745 
1746 	strlist__for_each(pos, trace->ev_qualifier) {
1747 		const char *sc = pos->s;
1748 		int id = audit_name_to_syscall(sc, trace->audit.machine);
1749 
1750 		if (id < 0) {
1751 			if (err == 0) {
1752 				fputs("Error:\tInvalid syscall ", trace->output);
1753 				err = -EINVAL;
1754 			} else {
1755 				fputs(", ", trace->output);
1756 			}
1757 
1758 			fputs(sc, trace->output);
1759 		}
1760 
1761 		trace->ev_qualifier_ids.entries[i++] = id;
1762 	}
1763 
1764 	if (err < 0) {
1765 		fputs("\nHint:\ttry 'perf list syscalls:sys_enter_*'"
1766 		      "\nHint:\tand: 'man syscalls'\n", trace->output);
1767 		zfree(&trace->ev_qualifier_ids.entries);
1768 		trace->ev_qualifier_ids.nr = 0;
1769 	}
1770 out:
1771 	return err;
1772 }
1773 
1774 /*
1775  * args is to be interpreted as a series of longs but we need to handle
1776  * 8-byte unaligned accesses. args points to raw_data within the event
1777  * and raw_data is guaranteed to be 8-byte unaligned because it is
1778  * preceded by raw_size which is a u32. So we need to copy args to a temp
1779  * variable to read it. Most notably this avoids extended load instructions
1780  * on unaligned addresses
1781  */
1782 
1783 static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
1784 				      unsigned char *args, struct trace *trace,
1785 				      struct thread *thread)
1786 {
1787 	size_t printed = 0;
1788 	unsigned char *p;
1789 	unsigned long val;
1790 
1791 	if (sc->args != NULL) {
1792 		struct format_field *field;
1793 		u8 bit = 1;
1794 		struct syscall_arg arg = {
1795 			.idx	= 0,
1796 			.mask	= 0,
1797 			.trace  = trace,
1798 			.thread = thread,
1799 		};
1800 
1801 		for (field = sc->args; field;
1802 		     field = field->next, ++arg.idx, bit <<= 1) {
1803 			if (arg.mask & bit)
1804 				continue;
1805 
1806 			/* special care for unaligned accesses */
1807 			p = args + sizeof(unsigned long) * arg.idx;
1808 			memcpy(&val, p, sizeof(val));
1809 
1810 			/*
1811  			 * Suppress this argument if its value is zero and
1812  			 * and we don't have a string associated in an
1813  			 * strarray for it.
1814  			 */
1815 			if (val == 0 &&
1816 			    !(sc->arg_scnprintf &&
1817 			      sc->arg_scnprintf[arg.idx] == SCA_STRARRAY &&
1818 			      sc->arg_parm[arg.idx]))
1819 				continue;
1820 
1821 			printed += scnprintf(bf + printed, size - printed,
1822 					     "%s%s: ", printed ? ", " : "", field->name);
1823 			if (sc->arg_scnprintf && sc->arg_scnprintf[arg.idx]) {
1824 				arg.val = val;
1825 				if (sc->arg_parm)
1826 					arg.parm = sc->arg_parm[arg.idx];
1827 				printed += sc->arg_scnprintf[arg.idx](bf + printed,
1828 								      size - printed, &arg);
1829 			} else {
1830 				printed += scnprintf(bf + printed, size - printed,
1831 						     "%ld", val);
1832 			}
1833 		}
1834 	} else {
1835 		int i = 0;
1836 
1837 		while (i < 6) {
1838 			/* special care for unaligned accesses */
1839 			p = args + sizeof(unsigned long) * i;
1840 			memcpy(&val, p, sizeof(val));
1841 			printed += scnprintf(bf + printed, size - printed,
1842 					     "%sarg%d: %ld",
1843 					     printed ? ", " : "", i, val);
1844 			++i;
1845 		}
1846 	}
1847 
1848 	return printed;
1849 }
1850 
1851 typedef int (*tracepoint_handler)(struct trace *trace, struct perf_evsel *evsel,
1852 				  union perf_event *event,
1853 				  struct perf_sample *sample);
1854 
1855 static struct syscall *trace__syscall_info(struct trace *trace,
1856 					   struct perf_evsel *evsel, int id)
1857 {
1858 
1859 	if (id < 0) {
1860 
1861 		/*
1862 		 * XXX: Noticed on x86_64, reproduced as far back as 3.0.36, haven't tried
1863 		 * before that, leaving at a higher verbosity level till that is
1864 		 * explained. Reproduced with plain ftrace with:
1865 		 *
1866 		 * echo 1 > /t/events/raw_syscalls/sys_exit/enable
1867 		 * grep "NR -1 " /t/trace_pipe
1868 		 *
1869 		 * After generating some load on the machine.
1870  		 */
1871 		if (verbose > 1) {
1872 			static u64 n;
1873 			fprintf(trace->output, "Invalid syscall %d id, skipping (%s, %" PRIu64 ") ...\n",
1874 				id, perf_evsel__name(evsel), ++n);
1875 		}
1876 		return NULL;
1877 	}
1878 
1879 	if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) &&
1880 	    trace__read_syscall_info(trace, id))
1881 		goto out_cant_read;
1882 
1883 	if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL))
1884 		goto out_cant_read;
1885 
1886 	return &trace->syscalls.table[id];
1887 
1888 out_cant_read:
1889 	if (verbose) {
1890 		fprintf(trace->output, "Problems reading syscall %d", id);
1891 		if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL)
1892 			fprintf(trace->output, "(%s)", trace->syscalls.table[id].name);
1893 		fputs(" information\n", trace->output);
1894 	}
1895 	return NULL;
1896 }
1897 
1898 static void thread__update_stats(struct thread_trace *ttrace,
1899 				 int id, struct perf_sample *sample)
1900 {
1901 	struct int_node *inode;
1902 	struct stats *stats;
1903 	u64 duration = 0;
1904 
1905 	inode = intlist__findnew(ttrace->syscall_stats, id);
1906 	if (inode == NULL)
1907 		return;
1908 
1909 	stats = inode->priv;
1910 	if (stats == NULL) {
1911 		stats = malloc(sizeof(struct stats));
1912 		if (stats == NULL)
1913 			return;
1914 		init_stats(stats);
1915 		inode->priv = stats;
1916 	}
1917 
1918 	if (ttrace->entry_time && sample->time > ttrace->entry_time)
1919 		duration = sample->time - ttrace->entry_time;
1920 
1921 	update_stats(stats, duration);
1922 }
1923 
1924 static int trace__printf_interrupted_entry(struct trace *trace, struct perf_sample *sample)
1925 {
1926 	struct thread_trace *ttrace;
1927 	u64 duration;
1928 	size_t printed;
1929 
1930 	if (trace->current == NULL)
1931 		return 0;
1932 
1933 	ttrace = thread__priv(trace->current);
1934 
1935 	if (!ttrace->entry_pending)
1936 		return 0;
1937 
1938 	duration = sample->time - ttrace->entry_time;
1939 
1940 	printed  = trace__fprintf_entry_head(trace, trace->current, duration, sample->time, trace->output);
1941 	printed += fprintf(trace->output, "%-70s) ...\n", ttrace->entry_str);
1942 	ttrace->entry_pending = false;
1943 
1944 	return printed;
1945 }
1946 
1947 static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
1948 			    union perf_event *event __maybe_unused,
1949 			    struct perf_sample *sample)
1950 {
1951 	char *msg;
1952 	void *args;
1953 	size_t printed = 0;
1954 	struct thread *thread;
1955 	int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
1956 	struct syscall *sc = trace__syscall_info(trace, evsel, id);
1957 	struct thread_trace *ttrace;
1958 
1959 	if (sc == NULL)
1960 		return -1;
1961 
1962 	thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
1963 	ttrace = thread__trace(thread, trace->output);
1964 	if (ttrace == NULL)
1965 		goto out_put;
1966 
1967 	args = perf_evsel__sc_tp_ptr(evsel, args, sample);
1968 
1969 	if (ttrace->entry_str == NULL) {
1970 		ttrace->entry_str = malloc(trace__entry_str_size);
1971 		if (!ttrace->entry_str)
1972 			goto out_put;
1973 	}
1974 
1975 	if (!trace->summary_only)
1976 		trace__printf_interrupted_entry(trace, sample);
1977 
1978 	ttrace->entry_time = sample->time;
1979 	msg = ttrace->entry_str;
1980 	printed += scnprintf(msg + printed, trace__entry_str_size - printed, "%s(", sc->name);
1981 
1982 	printed += syscall__scnprintf_args(sc, msg + printed, trace__entry_str_size - printed,
1983 					   args, trace, thread);
1984 
1985 	if (sc->is_exit) {
1986 		if (!trace->duration_filter && !trace->summary_only) {
1987 			trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output);
1988 			fprintf(trace->output, "%-70s\n", ttrace->entry_str);
1989 		}
1990 	} else {
1991 		ttrace->entry_pending = true;
1992 		/* See trace__vfs_getname & trace__sys_exit */
1993 		ttrace->filename.pending_open = false;
1994 	}
1995 
1996 	if (trace->current != thread) {
1997 		thread__put(trace->current);
1998 		trace->current = thread__get(thread);
1999 	}
2000 	err = 0;
2001 out_put:
2002 	thread__put(thread);
2003 	return err;
2004 }
2005 
2006 static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
2007 			   union perf_event *event __maybe_unused,
2008 			   struct perf_sample *sample)
2009 {
2010 	long ret;
2011 	u64 duration = 0;
2012 	struct thread *thread;
2013 	int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
2014 	struct syscall *sc = trace__syscall_info(trace, evsel, id);
2015 	struct thread_trace *ttrace;
2016 
2017 	if (sc == NULL)
2018 		return -1;
2019 
2020 	thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
2021 	ttrace = thread__trace(thread, trace->output);
2022 	if (ttrace == NULL)
2023 		goto out_put;
2024 
2025 	if (trace->summary)
2026 		thread__update_stats(ttrace, id, sample);
2027 
2028 	ret = perf_evsel__sc_tp_uint(evsel, ret, sample);
2029 
2030 	if (id == trace->audit.open_id && ret >= 0 && ttrace->filename.pending_open) {
2031 		trace__set_fd_pathname(thread, ret, ttrace->filename.name);
2032 		ttrace->filename.pending_open = false;
2033 		++trace->stats.vfs_getname;
2034 	}
2035 
2036 	ttrace->exit_time = sample->time;
2037 
2038 	if (ttrace->entry_time) {
2039 		duration = sample->time - ttrace->entry_time;
2040 		if (trace__filter_duration(trace, duration))
2041 			goto out;
2042 	} else if (trace->duration_filter)
2043 		goto out;
2044 
2045 	if (trace->summary_only)
2046 		goto out;
2047 
2048 	trace__fprintf_entry_head(trace, thread, duration, sample->time, trace->output);
2049 
2050 	if (ttrace->entry_pending) {
2051 		fprintf(trace->output, "%-70s", ttrace->entry_str);
2052 	} else {
2053 		fprintf(trace->output, " ... [");
2054 		color_fprintf(trace->output, PERF_COLOR_YELLOW, "continued");
2055 		fprintf(trace->output, "]: %s()", sc->name);
2056 	}
2057 
2058 	if (sc->fmt == NULL) {
2059 signed_print:
2060 		fprintf(trace->output, ") = %ld", ret);
2061 	} else if (ret < 0 && sc->fmt->errmsg) {
2062 		char bf[STRERR_BUFSIZE];
2063 		const char *emsg = strerror_r(-ret, bf, sizeof(bf)),
2064 			   *e = audit_errno_to_name(-ret);
2065 
2066 		fprintf(trace->output, ") = -1 %s %s", e, emsg);
2067 	} else if (ret == 0 && sc->fmt->timeout)
2068 		fprintf(trace->output, ") = 0 Timeout");
2069 	else if (sc->fmt->hexret)
2070 		fprintf(trace->output, ") = %#lx", ret);
2071 	else
2072 		goto signed_print;
2073 
2074 	fputc('\n', trace->output);
2075 out:
2076 	ttrace->entry_pending = false;
2077 	err = 0;
2078 out_put:
2079 	thread__put(thread);
2080 	return err;
2081 }
2082 
2083 static int trace__vfs_getname(struct trace *trace, struct perf_evsel *evsel,
2084 			      union perf_event *event __maybe_unused,
2085 			      struct perf_sample *sample)
2086 {
2087 	struct thread *thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
2088 	struct thread_trace *ttrace;
2089 	size_t filename_len, entry_str_len, to_move;
2090 	ssize_t remaining_space;
2091 	char *pos;
2092 	const char *filename = perf_evsel__rawptr(evsel, sample, "pathname");
2093 
2094 	if (!thread)
2095 		goto out;
2096 
2097 	ttrace = thread__priv(thread);
2098 	if (!ttrace)
2099 		goto out;
2100 
2101 	filename_len = strlen(filename);
2102 
2103 	if (ttrace->filename.namelen < filename_len) {
2104 		char *f = realloc(ttrace->filename.name, filename_len + 1);
2105 
2106 		if (f == NULL)
2107 				goto out;
2108 
2109 		ttrace->filename.namelen = filename_len;
2110 		ttrace->filename.name = f;
2111 	}
2112 
2113 	strcpy(ttrace->filename.name, filename);
2114 	ttrace->filename.pending_open = true;
2115 
2116 	if (!ttrace->filename.ptr)
2117 		goto out;
2118 
2119 	entry_str_len = strlen(ttrace->entry_str);
2120 	remaining_space = trace__entry_str_size - entry_str_len - 1; /* \0 */
2121 	if (remaining_space <= 0)
2122 		goto out;
2123 
2124 	if (filename_len > (size_t)remaining_space) {
2125 		filename += filename_len - remaining_space;
2126 		filename_len = remaining_space;
2127 	}
2128 
2129 	to_move = entry_str_len - ttrace->filename.entry_str_pos + 1; /* \0 */
2130 	pos = ttrace->entry_str + ttrace->filename.entry_str_pos;
2131 	memmove(pos + filename_len, pos, to_move);
2132 	memcpy(pos, filename, filename_len);
2133 
2134 	ttrace->filename.ptr = 0;
2135 	ttrace->filename.entry_str_pos = 0;
2136 out:
2137 	return 0;
2138 }
2139 
2140 static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evsel,
2141 				     union perf_event *event __maybe_unused,
2142 				     struct perf_sample *sample)
2143 {
2144         u64 runtime = perf_evsel__intval(evsel, sample, "runtime");
2145 	double runtime_ms = (double)runtime / NSEC_PER_MSEC;
2146 	struct thread *thread = machine__findnew_thread(trace->host,
2147 							sample->pid,
2148 							sample->tid);
2149 	struct thread_trace *ttrace = thread__trace(thread, trace->output);
2150 
2151 	if (ttrace == NULL)
2152 		goto out_dump;
2153 
2154 	ttrace->runtime_ms += runtime_ms;
2155 	trace->runtime_ms += runtime_ms;
2156 	thread__put(thread);
2157 	return 0;
2158 
2159 out_dump:
2160 	fprintf(trace->output, "%s: comm=%s,pid=%u,runtime=%" PRIu64 ",vruntime=%" PRIu64 ")\n",
2161 	       evsel->name,
2162 	       perf_evsel__strval(evsel, sample, "comm"),
2163 	       (pid_t)perf_evsel__intval(evsel, sample, "pid"),
2164 	       runtime,
2165 	       perf_evsel__intval(evsel, sample, "vruntime"));
2166 	thread__put(thread);
2167 	return 0;
2168 }
2169 
2170 static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel,
2171 				union perf_event *event __maybe_unused,
2172 				struct perf_sample *sample)
2173 {
2174 	trace__printf_interrupted_entry(trace, sample);
2175 	trace__fprintf_tstamp(trace, sample->time, trace->output);
2176 
2177 	if (trace->trace_syscalls)
2178 		fprintf(trace->output, "(         ): ");
2179 
2180 	fprintf(trace->output, "%s:", evsel->name);
2181 
2182 	if (evsel->tp_format) {
2183 		event_format__fprintf(evsel->tp_format, sample->cpu,
2184 				      sample->raw_data, sample->raw_size,
2185 				      trace->output);
2186 	}
2187 
2188 	fprintf(trace->output, ")\n");
2189 	return 0;
2190 }
2191 
2192 static void print_location(FILE *f, struct perf_sample *sample,
2193 			   struct addr_location *al,
2194 			   bool print_dso, bool print_sym)
2195 {
2196 
2197 	if ((verbose || print_dso) && al->map)
2198 		fprintf(f, "%s@", al->map->dso->long_name);
2199 
2200 	if ((verbose || print_sym) && al->sym)
2201 		fprintf(f, "%s+0x%" PRIx64, al->sym->name,
2202 			al->addr - al->sym->start);
2203 	else if (al->map)
2204 		fprintf(f, "0x%" PRIx64, al->addr);
2205 	else
2206 		fprintf(f, "0x%" PRIx64, sample->addr);
2207 }
2208 
2209 static int trace__pgfault(struct trace *trace,
2210 			  struct perf_evsel *evsel,
2211 			  union perf_event *event,
2212 			  struct perf_sample *sample)
2213 {
2214 	struct thread *thread;
2215 	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
2216 	struct addr_location al;
2217 	char map_type = 'd';
2218 	struct thread_trace *ttrace;
2219 	int err = -1;
2220 
2221 	thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
2222 	ttrace = thread__trace(thread, trace->output);
2223 	if (ttrace == NULL)
2224 		goto out_put;
2225 
2226 	if (evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)
2227 		ttrace->pfmaj++;
2228 	else
2229 		ttrace->pfmin++;
2230 
2231 	if (trace->summary_only)
2232 		goto out;
2233 
2234 	thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
2235 			      sample->ip, &al);
2236 
2237 	trace__fprintf_entry_head(trace, thread, 0, sample->time, trace->output);
2238 
2239 	fprintf(trace->output, "%sfault [",
2240 		evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ?
2241 		"maj" : "min");
2242 
2243 	print_location(trace->output, sample, &al, false, true);
2244 
2245 	fprintf(trace->output, "] => ");
2246 
2247 	thread__find_addr_location(thread, cpumode, MAP__VARIABLE,
2248 				   sample->addr, &al);
2249 
2250 	if (!al.map) {
2251 		thread__find_addr_location(thread, cpumode,
2252 					   MAP__FUNCTION, sample->addr, &al);
2253 
2254 		if (al.map)
2255 			map_type = 'x';
2256 		else
2257 			map_type = '?';
2258 	}
2259 
2260 	print_location(trace->output, sample, &al, true, false);
2261 
2262 	fprintf(trace->output, " (%c%c)\n", map_type, al.level);
2263 out:
2264 	err = 0;
2265 out_put:
2266 	thread__put(thread);
2267 	return err;
2268 }
2269 
2270 static bool skip_sample(struct trace *trace, struct perf_sample *sample)
2271 {
2272 	if ((trace->pid_list && intlist__find(trace->pid_list, sample->pid)) ||
2273 	    (trace->tid_list && intlist__find(trace->tid_list, sample->tid)))
2274 		return false;
2275 
2276 	if (trace->pid_list || trace->tid_list)
2277 		return true;
2278 
2279 	return false;
2280 }
2281 
2282 static int trace__process_sample(struct perf_tool *tool,
2283 				 union perf_event *event,
2284 				 struct perf_sample *sample,
2285 				 struct perf_evsel *evsel,
2286 				 struct machine *machine __maybe_unused)
2287 {
2288 	struct trace *trace = container_of(tool, struct trace, tool);
2289 	int err = 0;
2290 
2291 	tracepoint_handler handler = evsel->handler;
2292 
2293 	if (skip_sample(trace, sample))
2294 		return 0;
2295 
2296 	if (!trace->full_time && trace->base_time == 0)
2297 		trace->base_time = sample->time;
2298 
2299 	if (handler) {
2300 		++trace->nr_events;
2301 		handler(trace, evsel, event, sample);
2302 	}
2303 
2304 	return err;
2305 }
2306 
2307 static int parse_target_str(struct trace *trace)
2308 {
2309 	if (trace->opts.target.pid) {
2310 		trace->pid_list = intlist__new(trace->opts.target.pid);
2311 		if (trace->pid_list == NULL) {
2312 			pr_err("Error parsing process id string\n");
2313 			return -EINVAL;
2314 		}
2315 	}
2316 
2317 	if (trace->opts.target.tid) {
2318 		trace->tid_list = intlist__new(trace->opts.target.tid);
2319 		if (trace->tid_list == NULL) {
2320 			pr_err("Error parsing thread id string\n");
2321 			return -EINVAL;
2322 		}
2323 	}
2324 
2325 	return 0;
2326 }
2327 
2328 static int trace__record(struct trace *trace, int argc, const char **argv)
2329 {
2330 	unsigned int rec_argc, i, j;
2331 	const char **rec_argv;
2332 	const char * const record_args[] = {
2333 		"record",
2334 		"-R",
2335 		"-m", "1024",
2336 		"-c", "1",
2337 	};
2338 
2339 	const char * const sc_args[] = { "-e", };
2340 	unsigned int sc_args_nr = ARRAY_SIZE(sc_args);
2341 	const char * const majpf_args[] = { "-e", "major-faults" };
2342 	unsigned int majpf_args_nr = ARRAY_SIZE(majpf_args);
2343 	const char * const minpf_args[] = { "-e", "minor-faults" };
2344 	unsigned int minpf_args_nr = ARRAY_SIZE(minpf_args);
2345 
2346 	/* +1 is for the event string below */
2347 	rec_argc = ARRAY_SIZE(record_args) + sc_args_nr + 1 +
2348 		majpf_args_nr + minpf_args_nr + argc;
2349 	rec_argv = calloc(rec_argc + 1, sizeof(char *));
2350 
2351 	if (rec_argv == NULL)
2352 		return -ENOMEM;
2353 
2354 	j = 0;
2355 	for (i = 0; i < ARRAY_SIZE(record_args); i++)
2356 		rec_argv[j++] = record_args[i];
2357 
2358 	if (trace->trace_syscalls) {
2359 		for (i = 0; i < sc_args_nr; i++)
2360 			rec_argv[j++] = sc_args[i];
2361 
2362 		/* event string may be different for older kernels - e.g., RHEL6 */
2363 		if (is_valid_tracepoint("raw_syscalls:sys_enter"))
2364 			rec_argv[j++] = "raw_syscalls:sys_enter,raw_syscalls:sys_exit";
2365 		else if (is_valid_tracepoint("syscalls:sys_enter"))
2366 			rec_argv[j++] = "syscalls:sys_enter,syscalls:sys_exit";
2367 		else {
2368 			pr_err("Neither raw_syscalls nor syscalls events exist.\n");
2369 			return -1;
2370 		}
2371 	}
2372 
2373 	if (trace->trace_pgfaults & TRACE_PFMAJ)
2374 		for (i = 0; i < majpf_args_nr; i++)
2375 			rec_argv[j++] = majpf_args[i];
2376 
2377 	if (trace->trace_pgfaults & TRACE_PFMIN)
2378 		for (i = 0; i < minpf_args_nr; i++)
2379 			rec_argv[j++] = minpf_args[i];
2380 
2381 	for (i = 0; i < (unsigned int)argc; i++)
2382 		rec_argv[j++] = argv[i];
2383 
2384 	return cmd_record(j, rec_argv, NULL);
2385 }
2386 
2387 static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp);
2388 
2389 static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist)
2390 {
2391 	struct perf_evsel *evsel = perf_evsel__newtp("probe", "vfs_getname");
2392 	if (evsel == NULL)
2393 		return false;
2394 
2395 	if (perf_evsel__field(evsel, "pathname") == NULL) {
2396 		perf_evsel__delete(evsel);
2397 		return false;
2398 	}
2399 
2400 	evsel->handler = trace__vfs_getname;
2401 	perf_evlist__add(evlist, evsel);
2402 	return true;
2403 }
2404 
2405 static int perf_evlist__add_pgfault(struct perf_evlist *evlist,
2406 				    u64 config)
2407 {
2408 	struct perf_evsel *evsel;
2409 	struct perf_event_attr attr = {
2410 		.type = PERF_TYPE_SOFTWARE,
2411 		.mmap_data = 1,
2412 	};
2413 
2414 	attr.config = config;
2415 	attr.sample_period = 1;
2416 
2417 	event_attr_init(&attr);
2418 
2419 	evsel = perf_evsel__new(&attr);
2420 	if (!evsel)
2421 		return -ENOMEM;
2422 
2423 	evsel->handler = trace__pgfault;
2424 	perf_evlist__add(evlist, evsel);
2425 
2426 	return 0;
2427 }
2428 
2429 static void trace__handle_event(struct trace *trace, union perf_event *event, struct perf_sample *sample)
2430 {
2431 	const u32 type = event->header.type;
2432 	struct perf_evsel *evsel;
2433 
2434 	if (!trace->full_time && trace->base_time == 0)
2435 		trace->base_time = sample->time;
2436 
2437 	if (type != PERF_RECORD_SAMPLE) {
2438 		trace__process_event(trace, trace->host, event, sample);
2439 		return;
2440 	}
2441 
2442 	evsel = perf_evlist__id2evsel(trace->evlist, sample->id);
2443 	if (evsel == NULL) {
2444 		fprintf(trace->output, "Unknown tp ID %" PRIu64 ", skipping...\n", sample->id);
2445 		return;
2446 	}
2447 
2448 	if (evsel->attr.type == PERF_TYPE_TRACEPOINT &&
2449 	    sample->raw_data == NULL) {
2450 		fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
2451 		       perf_evsel__name(evsel), sample->tid,
2452 		       sample->cpu, sample->raw_size);
2453 	} else {
2454 		tracepoint_handler handler = evsel->handler;
2455 		handler(trace, evsel, event, sample);
2456 	}
2457 }
2458 
2459 static int trace__add_syscall_newtp(struct trace *trace)
2460 {
2461 	int ret = -1;
2462 	struct perf_evlist *evlist = trace->evlist;
2463 	struct perf_evsel *sys_enter, *sys_exit;
2464 
2465 	sys_enter = perf_evsel__syscall_newtp("sys_enter", trace__sys_enter);
2466 	if (sys_enter == NULL)
2467 		goto out;
2468 
2469 	if (perf_evsel__init_sc_tp_ptr_field(sys_enter, args))
2470 		goto out_delete_sys_enter;
2471 
2472 	sys_exit = perf_evsel__syscall_newtp("sys_exit", trace__sys_exit);
2473 	if (sys_exit == NULL)
2474 		goto out_delete_sys_enter;
2475 
2476 	if (perf_evsel__init_sc_tp_uint_field(sys_exit, ret))
2477 		goto out_delete_sys_exit;
2478 
2479 	perf_evlist__add(evlist, sys_enter);
2480 	perf_evlist__add(evlist, sys_exit);
2481 
2482 	trace->syscalls.events.sys_enter = sys_enter;
2483 	trace->syscalls.events.sys_exit  = sys_exit;
2484 
2485 	ret = 0;
2486 out:
2487 	return ret;
2488 
2489 out_delete_sys_exit:
2490 	perf_evsel__delete_priv(sys_exit);
2491 out_delete_sys_enter:
2492 	perf_evsel__delete_priv(sys_enter);
2493 	goto out;
2494 }
2495 
2496 static int trace__set_ev_qualifier_filter(struct trace *trace)
2497 {
2498 	int err = -1;
2499 	char *filter = asprintf_expr_inout_ints("id", !trace->not_ev_qualifier,
2500 						trace->ev_qualifier_ids.nr,
2501 						trace->ev_qualifier_ids.entries);
2502 
2503 	if (filter == NULL)
2504 		goto out_enomem;
2505 
2506 	if (!perf_evsel__append_filter(trace->syscalls.events.sys_enter, "&&", filter))
2507 		err = perf_evsel__append_filter(trace->syscalls.events.sys_exit, "&&", filter);
2508 
2509 	free(filter);
2510 out:
2511 	return err;
2512 out_enomem:
2513 	errno = ENOMEM;
2514 	goto out;
2515 }
2516 
2517 static int trace__run(struct trace *trace, int argc, const char **argv)
2518 {
2519 	struct perf_evlist *evlist = trace->evlist;
2520 	struct perf_evsel *evsel;
2521 	int err = -1, i;
2522 	unsigned long before;
2523 	const bool forks = argc > 0;
2524 	bool draining = false;
2525 
2526 	trace->live = true;
2527 
2528 	if (trace->trace_syscalls && trace__add_syscall_newtp(trace))
2529 		goto out_error_raw_syscalls;
2530 
2531 	if (trace->trace_syscalls)
2532 		trace->vfs_getname = perf_evlist__add_vfs_getname(evlist);
2533 
2534 	if ((trace->trace_pgfaults & TRACE_PFMAJ) &&
2535 	    perf_evlist__add_pgfault(evlist, PERF_COUNT_SW_PAGE_FAULTS_MAJ)) {
2536 		goto out_error_mem;
2537 	}
2538 
2539 	if ((trace->trace_pgfaults & TRACE_PFMIN) &&
2540 	    perf_evlist__add_pgfault(evlist, PERF_COUNT_SW_PAGE_FAULTS_MIN))
2541 		goto out_error_mem;
2542 
2543 	if (trace->sched &&
2544 	    perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime",
2545 				   trace__sched_stat_runtime))
2546 		goto out_error_sched_stat_runtime;
2547 
2548 	err = perf_evlist__create_maps(evlist, &trace->opts.target);
2549 	if (err < 0) {
2550 		fprintf(trace->output, "Problems parsing the target to trace, check your options!\n");
2551 		goto out_delete_evlist;
2552 	}
2553 
2554 	err = trace__symbols_init(trace, evlist);
2555 	if (err < 0) {
2556 		fprintf(trace->output, "Problems initializing symbol libraries!\n");
2557 		goto out_delete_evlist;
2558 	}
2559 
2560 	perf_evlist__config(evlist, &trace->opts);
2561 
2562 	signal(SIGCHLD, sig_handler);
2563 	signal(SIGINT, sig_handler);
2564 
2565 	if (forks) {
2566 		err = perf_evlist__prepare_workload(evlist, &trace->opts.target,
2567 						    argv, false, NULL);
2568 		if (err < 0) {
2569 			fprintf(trace->output, "Couldn't run the workload!\n");
2570 			goto out_delete_evlist;
2571 		}
2572 	}
2573 
2574 	err = perf_evlist__open(evlist);
2575 	if (err < 0)
2576 		goto out_error_open;
2577 
2578 	/*
2579 	 * Better not use !target__has_task() here because we need to cover the
2580 	 * case where no threads were specified in the command line, but a
2581 	 * workload was, and in that case we will fill in the thread_map when
2582 	 * we fork the workload in perf_evlist__prepare_workload.
2583 	 */
2584 	if (trace->filter_pids.nr > 0)
2585 		err = perf_evlist__set_filter_pids(evlist, trace->filter_pids.nr, trace->filter_pids.entries);
2586 	else if (thread_map__pid(evlist->threads, 0) == -1)
2587 		err = perf_evlist__set_filter_pid(evlist, getpid());
2588 
2589 	if (err < 0)
2590 		goto out_error_mem;
2591 
2592 	if (trace->ev_qualifier_ids.nr > 0) {
2593 		err = trace__set_ev_qualifier_filter(trace);
2594 		if (err < 0)
2595 			goto out_errno;
2596 
2597 		pr_debug("event qualifier tracepoint filter: %s\n",
2598 			 trace->syscalls.events.sys_exit->filter);
2599 	}
2600 
2601 	err = perf_evlist__apply_filters(evlist, &evsel);
2602 	if (err < 0)
2603 		goto out_error_apply_filters;
2604 
2605 	err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false);
2606 	if (err < 0)
2607 		goto out_error_mmap;
2608 
2609 	if (!target__none(&trace->opts.target))
2610 		perf_evlist__enable(evlist);
2611 
2612 	if (forks)
2613 		perf_evlist__start_workload(evlist);
2614 
2615 	trace->multiple_threads = thread_map__pid(evlist->threads, 0) == -1 ||
2616 				  evlist->threads->nr > 1 ||
2617 				  perf_evlist__first(evlist)->attr.inherit;
2618 again:
2619 	before = trace->nr_events;
2620 
2621 	for (i = 0; i < evlist->nr_mmaps; i++) {
2622 		union perf_event *event;
2623 
2624 		while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
2625 			struct perf_sample sample;
2626 
2627 			++trace->nr_events;
2628 
2629 			err = perf_evlist__parse_sample(evlist, event, &sample);
2630 			if (err) {
2631 				fprintf(trace->output, "Can't parse sample, err = %d, skipping...\n", err);
2632 				goto next_event;
2633 			}
2634 
2635 			trace__handle_event(trace, event, &sample);
2636 next_event:
2637 			perf_evlist__mmap_consume(evlist, i);
2638 
2639 			if (interrupted)
2640 				goto out_disable;
2641 
2642 			if (done && !draining) {
2643 				perf_evlist__disable(evlist);
2644 				draining = true;
2645 			}
2646 		}
2647 	}
2648 
2649 	if (trace->nr_events == before) {
2650 		int timeout = done ? 100 : -1;
2651 
2652 		if (!draining && perf_evlist__poll(evlist, timeout) > 0) {
2653 			if (perf_evlist__filter_pollfd(evlist, POLLERR | POLLHUP) == 0)
2654 				draining = true;
2655 
2656 			goto again;
2657 		}
2658 	} else {
2659 		goto again;
2660 	}
2661 
2662 out_disable:
2663 	thread__zput(trace->current);
2664 
2665 	perf_evlist__disable(evlist);
2666 
2667 	if (!err) {
2668 		if (trace->summary)
2669 			trace__fprintf_thread_summary(trace, trace->output);
2670 
2671 		if (trace->show_tool_stats) {
2672 			fprintf(trace->output, "Stats:\n "
2673 					       " vfs_getname : %" PRIu64 "\n"
2674 					       " proc_getname: %" PRIu64 "\n",
2675 				trace->stats.vfs_getname,
2676 				trace->stats.proc_getname);
2677 		}
2678 	}
2679 
2680 out_delete_evlist:
2681 	perf_evlist__delete(evlist);
2682 	trace->evlist = NULL;
2683 	trace->live = false;
2684 	return err;
2685 {
2686 	char errbuf[BUFSIZ];
2687 
2688 out_error_sched_stat_runtime:
2689 	debugfs__strerror_open_tp(errno, errbuf, sizeof(errbuf), "sched", "sched_stat_runtime");
2690 	goto out_error;
2691 
2692 out_error_raw_syscalls:
2693 	debugfs__strerror_open_tp(errno, errbuf, sizeof(errbuf), "raw_syscalls", "sys_(enter|exit)");
2694 	goto out_error;
2695 
2696 out_error_mmap:
2697 	perf_evlist__strerror_mmap(evlist, errno, errbuf, sizeof(errbuf));
2698 	goto out_error;
2699 
2700 out_error_open:
2701 	perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf));
2702 
2703 out_error:
2704 	fprintf(trace->output, "%s\n", errbuf);
2705 	goto out_delete_evlist;
2706 
2707 out_error_apply_filters:
2708 	fprintf(trace->output,
2709 		"Failed to set filter \"%s\" on event %s with %d (%s)\n",
2710 		evsel->filter, perf_evsel__name(evsel), errno,
2711 		strerror_r(errno, errbuf, sizeof(errbuf)));
2712 	goto out_delete_evlist;
2713 }
2714 out_error_mem:
2715 	fprintf(trace->output, "Not enough memory to run!\n");
2716 	goto out_delete_evlist;
2717 
2718 out_errno:
2719 	fprintf(trace->output, "errno=%d,%s\n", errno, strerror(errno));
2720 	goto out_delete_evlist;
2721 }
2722 
2723 static int trace__replay(struct trace *trace)
2724 {
2725 	const struct perf_evsel_str_handler handlers[] = {
2726 		{ "probe:vfs_getname",	     trace__vfs_getname, },
2727 	};
2728 	struct perf_data_file file = {
2729 		.path  = input_name,
2730 		.mode  = PERF_DATA_MODE_READ,
2731 		.force = trace->force,
2732 	};
2733 	struct perf_session *session;
2734 	struct perf_evsel *evsel;
2735 	int err = -1;
2736 
2737 	trace->tool.sample	  = trace__process_sample;
2738 	trace->tool.mmap	  = perf_event__process_mmap;
2739 	trace->tool.mmap2	  = perf_event__process_mmap2;
2740 	trace->tool.comm	  = perf_event__process_comm;
2741 	trace->tool.exit	  = perf_event__process_exit;
2742 	trace->tool.fork	  = perf_event__process_fork;
2743 	trace->tool.attr	  = perf_event__process_attr;
2744 	trace->tool.tracing_data = perf_event__process_tracing_data;
2745 	trace->tool.build_id	  = perf_event__process_build_id;
2746 
2747 	trace->tool.ordered_events = true;
2748 	trace->tool.ordering_requires_timestamps = true;
2749 
2750 	/* add tid to output */
2751 	trace->multiple_threads = true;
2752 
2753 	session = perf_session__new(&file, false, &trace->tool);
2754 	if (session == NULL)
2755 		return -1;
2756 
2757 	if (symbol__init(&session->header.env) < 0)
2758 		goto out;
2759 
2760 	trace->host = &session->machines.host;
2761 
2762 	err = perf_session__set_tracepoints_handlers(session, handlers);
2763 	if (err)
2764 		goto out;
2765 
2766 	evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2767 						     "raw_syscalls:sys_enter");
2768 	/* older kernels have syscalls tp versus raw_syscalls */
2769 	if (evsel == NULL)
2770 		evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2771 							     "syscalls:sys_enter");
2772 
2773 	if (evsel &&
2774 	    (perf_evsel__init_syscall_tp(evsel, trace__sys_enter) < 0 ||
2775 	    perf_evsel__init_sc_tp_ptr_field(evsel, args))) {
2776 		pr_err("Error during initialize raw_syscalls:sys_enter event\n");
2777 		goto out;
2778 	}
2779 
2780 	evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2781 						     "raw_syscalls:sys_exit");
2782 	if (evsel == NULL)
2783 		evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2784 							     "syscalls:sys_exit");
2785 	if (evsel &&
2786 	    (perf_evsel__init_syscall_tp(evsel, trace__sys_exit) < 0 ||
2787 	    perf_evsel__init_sc_tp_uint_field(evsel, ret))) {
2788 		pr_err("Error during initialize raw_syscalls:sys_exit event\n");
2789 		goto out;
2790 	}
2791 
2792 	evlist__for_each(session->evlist, evsel) {
2793 		if (evsel->attr.type == PERF_TYPE_SOFTWARE &&
2794 		    (evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ||
2795 		     evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MIN ||
2796 		     evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS))
2797 			evsel->handler = trace__pgfault;
2798 	}
2799 
2800 	err = parse_target_str(trace);
2801 	if (err != 0)
2802 		goto out;
2803 
2804 	setup_pager();
2805 
2806 	err = perf_session__process_events(session);
2807 	if (err)
2808 		pr_err("Failed to process events, error %d", err);
2809 
2810 	else if (trace->summary)
2811 		trace__fprintf_thread_summary(trace, trace->output);
2812 
2813 out:
2814 	perf_session__delete(session);
2815 
2816 	return err;
2817 }
2818 
2819 static size_t trace__fprintf_threads_header(FILE *fp)
2820 {
2821 	size_t printed;
2822 
2823 	printed  = fprintf(fp, "\n Summary of events:\n\n");
2824 
2825 	return printed;
2826 }
2827 
2828 static size_t thread__dump_stats(struct thread_trace *ttrace,
2829 				 struct trace *trace, FILE *fp)
2830 {
2831 	struct stats *stats;
2832 	size_t printed = 0;
2833 	struct syscall *sc;
2834 	struct int_node *inode = intlist__first(ttrace->syscall_stats);
2835 
2836 	if (inode == NULL)
2837 		return 0;
2838 
2839 	printed += fprintf(fp, "\n");
2840 
2841 	printed += fprintf(fp, "   syscall            calls    total       min       avg       max      stddev\n");
2842 	printed += fprintf(fp, "                               (msec)    (msec)    (msec)    (msec)        (%%)\n");
2843 	printed += fprintf(fp, "   --------------- -------- --------- --------- --------- ---------     ------\n");
2844 
2845 	/* each int_node is a syscall */
2846 	while (inode) {
2847 		stats = inode->priv;
2848 		if (stats) {
2849 			double min = (double)(stats->min) / NSEC_PER_MSEC;
2850 			double max = (double)(stats->max) / NSEC_PER_MSEC;
2851 			double avg = avg_stats(stats);
2852 			double pct;
2853 			u64 n = (u64) stats->n;
2854 
2855 			pct = avg ? 100.0 * stddev_stats(stats)/avg : 0.0;
2856 			avg /= NSEC_PER_MSEC;
2857 
2858 			sc = &trace->syscalls.table[inode->i];
2859 			printed += fprintf(fp, "   %-15s", sc->name);
2860 			printed += fprintf(fp, " %8" PRIu64 " %9.3f %9.3f %9.3f",
2861 					   n, avg * n, min, avg);
2862 			printed += fprintf(fp, " %9.3f %9.2f%%\n", max, pct);
2863 		}
2864 
2865 		inode = intlist__next(inode);
2866 	}
2867 
2868 	printed += fprintf(fp, "\n\n");
2869 
2870 	return printed;
2871 }
2872 
2873 /* struct used to pass data to per-thread function */
2874 struct summary_data {
2875 	FILE *fp;
2876 	struct trace *trace;
2877 	size_t printed;
2878 };
2879 
2880 static int trace__fprintf_one_thread(struct thread *thread, void *priv)
2881 {
2882 	struct summary_data *data = priv;
2883 	FILE *fp = data->fp;
2884 	size_t printed = data->printed;
2885 	struct trace *trace = data->trace;
2886 	struct thread_trace *ttrace = thread__priv(thread);
2887 	double ratio;
2888 
2889 	if (ttrace == NULL)
2890 		return 0;
2891 
2892 	ratio = (double)ttrace->nr_events / trace->nr_events * 100.0;
2893 
2894 	printed += fprintf(fp, " %s (%d), ", thread__comm_str(thread), thread->tid);
2895 	printed += fprintf(fp, "%lu events, ", ttrace->nr_events);
2896 	printed += fprintf(fp, "%.1f%%", ratio);
2897 	if (ttrace->pfmaj)
2898 		printed += fprintf(fp, ", %lu majfaults", ttrace->pfmaj);
2899 	if (ttrace->pfmin)
2900 		printed += fprintf(fp, ", %lu minfaults", ttrace->pfmin);
2901 	printed += fprintf(fp, ", %.3f msec\n", ttrace->runtime_ms);
2902 	printed += thread__dump_stats(ttrace, trace, fp);
2903 
2904 	data->printed += printed;
2905 
2906 	return 0;
2907 }
2908 
2909 static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
2910 {
2911 	struct summary_data data = {
2912 		.fp = fp,
2913 		.trace = trace
2914 	};
2915 	data.printed = trace__fprintf_threads_header(fp);
2916 
2917 	machine__for_each_thread(trace->host, trace__fprintf_one_thread, &data);
2918 
2919 	return data.printed;
2920 }
2921 
2922 static int trace__set_duration(const struct option *opt, const char *str,
2923 			       int unset __maybe_unused)
2924 {
2925 	struct trace *trace = opt->value;
2926 
2927 	trace->duration_filter = atof(str);
2928 	return 0;
2929 }
2930 
2931 static int trace__set_filter_pids(const struct option *opt, const char *str,
2932 				  int unset __maybe_unused)
2933 {
2934 	int ret = -1;
2935 	size_t i;
2936 	struct trace *trace = opt->value;
2937 	/*
2938 	 * FIXME: introduce a intarray class, plain parse csv and create a
2939 	 * { int nr, int entries[] } struct...
2940 	 */
2941 	struct intlist *list = intlist__new(str);
2942 
2943 	if (list == NULL)
2944 		return -1;
2945 
2946 	i = trace->filter_pids.nr = intlist__nr_entries(list) + 1;
2947 	trace->filter_pids.entries = calloc(i, sizeof(pid_t));
2948 
2949 	if (trace->filter_pids.entries == NULL)
2950 		goto out;
2951 
2952 	trace->filter_pids.entries[0] = getpid();
2953 
2954 	for (i = 1; i < trace->filter_pids.nr; ++i)
2955 		trace->filter_pids.entries[i] = intlist__entry(list, i - 1)->i;
2956 
2957 	intlist__delete(list);
2958 	ret = 0;
2959 out:
2960 	return ret;
2961 }
2962 
2963 static int trace__open_output(struct trace *trace, const char *filename)
2964 {
2965 	struct stat st;
2966 
2967 	if (!stat(filename, &st) && st.st_size) {
2968 		char oldname[PATH_MAX];
2969 
2970 		scnprintf(oldname, sizeof(oldname), "%s.old", filename);
2971 		unlink(oldname);
2972 		rename(filename, oldname);
2973 	}
2974 
2975 	trace->output = fopen(filename, "w");
2976 
2977 	return trace->output == NULL ? -errno : 0;
2978 }
2979 
2980 static int parse_pagefaults(const struct option *opt, const char *str,
2981 			    int unset __maybe_unused)
2982 {
2983 	int *trace_pgfaults = opt->value;
2984 
2985 	if (strcmp(str, "all") == 0)
2986 		*trace_pgfaults |= TRACE_PFMAJ | TRACE_PFMIN;
2987 	else if (strcmp(str, "maj") == 0)
2988 		*trace_pgfaults |= TRACE_PFMAJ;
2989 	else if (strcmp(str, "min") == 0)
2990 		*trace_pgfaults |= TRACE_PFMIN;
2991 	else
2992 		return -1;
2993 
2994 	return 0;
2995 }
2996 
2997 static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler)
2998 {
2999 	struct perf_evsel *evsel;
3000 
3001 	evlist__for_each(evlist, evsel)
3002 		evsel->handler = handler;
3003 }
3004 
3005 int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
3006 {
3007 	const char *trace_usage[] = {
3008 		"perf trace [<options>] [<command>]",
3009 		"perf trace [<options>] -- <command> [<options>]",
3010 		"perf trace record [<options>] [<command>]",
3011 		"perf trace record [<options>] -- <command> [<options>]",
3012 		NULL
3013 	};
3014 	struct trace trace = {
3015 		.audit = {
3016 			.machine = audit_detect_machine(),
3017 			.open_id = audit_name_to_syscall("open", trace.audit.machine),
3018 		},
3019 		.syscalls = {
3020 			. max = -1,
3021 		},
3022 		.opts = {
3023 			.target = {
3024 				.uid	   = UINT_MAX,
3025 				.uses_mmap = true,
3026 			},
3027 			.user_freq     = UINT_MAX,
3028 			.user_interval = ULLONG_MAX,
3029 			.no_buffering  = true,
3030 			.mmap_pages    = UINT_MAX,
3031 			.proc_map_timeout  = 500,
3032 		},
3033 		.output = stderr,
3034 		.show_comm = true,
3035 		.trace_syscalls = true,
3036 	};
3037 	const char *output_name = NULL;
3038 	const char *ev_qualifier_str = NULL;
3039 	const struct option trace_options[] = {
3040 	OPT_CALLBACK(0, "event", &trace.evlist, "event",
3041 		     "event selector. use 'perf list' to list available events",
3042 		     parse_events_option),
3043 	OPT_BOOLEAN(0, "comm", &trace.show_comm,
3044 		    "show the thread COMM next to its id"),
3045 	OPT_BOOLEAN(0, "tool_stats", &trace.show_tool_stats, "show tool stats"),
3046 	OPT_STRING('e', "expr", &ev_qualifier_str, "expr", "list of syscalls to trace"),
3047 	OPT_STRING('o', "output", &output_name, "file", "output file name"),
3048 	OPT_STRING('i', "input", &input_name, "file", "Analyze events in file"),
3049 	OPT_STRING('p', "pid", &trace.opts.target.pid, "pid",
3050 		    "trace events on existing process id"),
3051 	OPT_STRING('t', "tid", &trace.opts.target.tid, "tid",
3052 		    "trace events on existing thread id"),
3053 	OPT_CALLBACK(0, "filter-pids", &trace, "CSV list of pids",
3054 		     "pids to filter (by the kernel)", trace__set_filter_pids),
3055 	OPT_BOOLEAN('a', "all-cpus", &trace.opts.target.system_wide,
3056 		    "system-wide collection from all CPUs"),
3057 	OPT_STRING('C', "cpu", &trace.opts.target.cpu_list, "cpu",
3058 		    "list of cpus to monitor"),
3059 	OPT_BOOLEAN(0, "no-inherit", &trace.opts.no_inherit,
3060 		    "child tasks do not inherit counters"),
3061 	OPT_CALLBACK('m', "mmap-pages", &trace.opts.mmap_pages, "pages",
3062 		     "number of mmap data pages",
3063 		     perf_evlist__parse_mmap_pages),
3064 	OPT_STRING('u', "uid", &trace.opts.target.uid_str, "user",
3065 		   "user to profile"),
3066 	OPT_CALLBACK(0, "duration", &trace, "float",
3067 		     "show only events with duration > N.M ms",
3068 		     trace__set_duration),
3069 	OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"),
3070 	OPT_INCR('v', "verbose", &verbose, "be more verbose"),
3071 	OPT_BOOLEAN('T', "time", &trace.full_time,
3072 		    "Show full timestamp, not time relative to first start"),
3073 	OPT_BOOLEAN('s', "summary", &trace.summary_only,
3074 		    "Show only syscall summary with statistics"),
3075 	OPT_BOOLEAN('S', "with-summary", &trace.summary,
3076 		    "Show all syscalls and summary with statistics"),
3077 	OPT_CALLBACK_DEFAULT('F', "pf", &trace.trace_pgfaults, "all|maj|min",
3078 		     "Trace pagefaults", parse_pagefaults, "maj"),
3079 	OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
3080 	OPT_BOOLEAN('f', "force", &trace.force, "don't complain, do it"),
3081 	OPT_UINTEGER(0, "proc-map-timeout", &trace.opts.proc_map_timeout,
3082 			"per thread proc mmap processing timeout in ms"),
3083 	OPT_END()
3084 	};
3085 	const char * const trace_subcommands[] = { "record", NULL };
3086 	int err;
3087 	char bf[BUFSIZ];
3088 
3089 	signal(SIGSEGV, sighandler_dump_stack);
3090 	signal(SIGFPE, sighandler_dump_stack);
3091 
3092 	trace.evlist = perf_evlist__new();
3093 
3094 	if (trace.evlist == NULL) {
3095 		pr_err("Not enough memory to run!\n");
3096 		err = -ENOMEM;
3097 		goto out;
3098 	}
3099 
3100 	argc = parse_options_subcommand(argc, argv, trace_options, trace_subcommands,
3101 				 trace_usage, PARSE_OPT_STOP_AT_NON_OPTION);
3102 
3103 	if (trace.trace_pgfaults) {
3104 		trace.opts.sample_address = true;
3105 		trace.opts.sample_time = true;
3106 	}
3107 
3108 	if (trace.evlist->nr_entries > 0)
3109 		evlist__set_evsel_handler(trace.evlist, trace__event_handler);
3110 
3111 	if ((argc >= 1) && (strcmp(argv[0], "record") == 0))
3112 		return trace__record(&trace, argc-1, &argv[1]);
3113 
3114 	/* summary_only implies summary option, but don't overwrite summary if set */
3115 	if (trace.summary_only)
3116 		trace.summary = trace.summary_only;
3117 
3118 	if (!trace.trace_syscalls && !trace.trace_pgfaults &&
3119 	    trace.evlist->nr_entries == 0 /* Was --events used? */) {
3120 		pr_err("Please specify something to trace.\n");
3121 		return -1;
3122 	}
3123 
3124 	if (output_name != NULL) {
3125 		err = trace__open_output(&trace, output_name);
3126 		if (err < 0) {
3127 			perror("failed to create output file");
3128 			goto out;
3129 		}
3130 	}
3131 
3132 	if (ev_qualifier_str != NULL) {
3133 		const char *s = ev_qualifier_str;
3134 		struct strlist_config slist_config = {
3135 			.dirname = system_path(STRACE_GROUPS_DIR),
3136 		};
3137 
3138 		trace.not_ev_qualifier = *s == '!';
3139 		if (trace.not_ev_qualifier)
3140 			++s;
3141 		trace.ev_qualifier = strlist__new(s, &slist_config);
3142 		if (trace.ev_qualifier == NULL) {
3143 			fputs("Not enough memory to parse event qualifier",
3144 			      trace.output);
3145 			err = -ENOMEM;
3146 			goto out_close;
3147 		}
3148 
3149 		err = trace__validate_ev_qualifier(&trace);
3150 		if (err)
3151 			goto out_close;
3152 	}
3153 
3154 	err = target__validate(&trace.opts.target);
3155 	if (err) {
3156 		target__strerror(&trace.opts.target, err, bf, sizeof(bf));
3157 		fprintf(trace.output, "%s", bf);
3158 		goto out_close;
3159 	}
3160 
3161 	err = target__parse_uid(&trace.opts.target);
3162 	if (err) {
3163 		target__strerror(&trace.opts.target, err, bf, sizeof(bf));
3164 		fprintf(trace.output, "%s", bf);
3165 		goto out_close;
3166 	}
3167 
3168 	if (!argc && target__none(&trace.opts.target))
3169 		trace.opts.target.system_wide = true;
3170 
3171 	if (input_name)
3172 		err = trace__replay(&trace);
3173 	else
3174 		err = trace__run(&trace, argc, argv);
3175 
3176 out_close:
3177 	if (output_name != NULL)
3178 		fclose(trace.output);
3179 out:
3180 	return err;
3181 }
3182