xref: /openbmc/linux/tools/perf/builtin-script.c (revision 57904291176fa16a981cefca5cbe1a0b50196792)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2133dc4c3SIngo Molnar #include "builtin.h"
3133dc4c3SIngo Molnar 
40f31c019SArnaldo Carvalho de Melo #include "util/counts.h"
5133dc4c3SIngo Molnar #include "util/debug.h"
64a3cec84SArnaldo Carvalho de Melo #include "util/dso.h"
74b6ab94eSJosh Poimboeuf #include <subcmd/exec-cmd.h>
8133dc4c3SIngo Molnar #include "util/header.h"
94b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h>
10fc36f948SStephane Eranian #include "util/perf_regs.h"
11133dc4c3SIngo Molnar #include "util/session.h"
1245694aa7SArnaldo Carvalho de Melo #include "util/tool.h"
131101f69aSArnaldo Carvalho de Melo #include "util/map.h"
1497b9d866SArnaldo Carvalho de Melo #include "util/srcline.h"
15133dc4c3SIngo Molnar #include "util/symbol.h"
16133dc4c3SIngo Molnar #include "util/thread.h"
17133dc4c3SIngo Molnar #include "util/trace-event.h"
1883869019SGerman Gomez #include "util/env.h"
191424dc96SDavid Ahern #include "util/evlist.h"
201424dc96SDavid Ahern #include "util/evsel.h"
21ca125277SArnaldo Carvalho de Melo #include "util/evsel_fprintf.h"
22d2360442SArnaldo Carvalho de Melo #include "util/evswitch.h"
2336385be5SFeng Tang #include "util/sort.h"
24f5fc1412SJiri Olsa #include "util/data.h"
257a680eb9SAdrian Hunter #include "util/auxtrace.h"
26cfc8874aSJiri Olsa #include "util/cpumap.h"
27cfc8874aSJiri Olsa #include "util/thread_map.h"
28cfc8874aSJiri Olsa #include "util/stat.h"
294bd1bef8SAndi Kleen #include "util/color.h"
30a067558eSArnaldo Carvalho de Melo #include "util/string2.h"
31e216708dSAdrian Hunter #include "util/thread-stack.h"
32a91f4c47SDavid Ahern #include "util/time-utils.h"
3306c3f2aaSJiri Olsa #include "util/path.h"
346b9bae63SKan Liang #include "util/event.h"
35fa0d9846SArnaldo Carvalho de Melo #include "ui/ui.h"
36fea01392SArnaldo Carvalho de Melo #include "print_binary.h"
373ab481a1SAndi Kleen #include "archinsn.h"
385d67be97SAnton Blanchard #include <linux/bitmap.h>
39877a7a11SArnaldo Carvalho de Melo #include <linux/kernel.h>
406125cc8dSArnaldo Carvalho de Melo #include <linux/stringify.h>
41bd48c63eSArnaldo Carvalho de Melo #include <linux/time64.h>
427f7c536fSArnaldo Carvalho de Melo #include <linux/zalloc.h>
433ab481a1SAndi Kleen #include <sys/utsname.h>
44cfc8874aSJiri Olsa #include "asm/bug.h"
45c19ac912SJiri Olsa #include "util/mem-events.h"
4648d02a1dSAndi Kleen #include "util/dump-insn.h"
4776b31a29SArnaldo Carvalho de Melo #include <dirent.h>
48a43783aeSArnaldo Carvalho de Melo #include <errno.h>
49fd20e811SArnaldo Carvalho de Melo #include <inttypes.h>
509607ad3aSArnaldo Carvalho de Melo #include <signal.h>
51391e4206SArnaldo Carvalho de Melo #include <sys/param.h>
527a8ef4c4SArnaldo Carvalho de Melo #include <sys/types.h>
537a8ef4c4SArnaldo Carvalho de Melo #include <sys/stat.h>
54bafae98eSArnaldo Carvalho de Melo #include <fcntl.h>
557a8ef4c4SArnaldo Carvalho de Melo #include <unistd.h>
56b585ebdbSAndi Kleen #include <subcmd/pager.h>
57453fa030SJiri Olsa #include <perf/evlist.h>
586ef81c55SMamatha Inamdar #include <linux/err.h>
59291961fcSAdrian Hunter #include "util/dlfilter.h"
60aeb00b1aSArnaldo Carvalho de Melo #include "util/record.h"
612da39f1cSArnaldo Carvalho de Melo #include "util/util.h"
623fd7a168SNamhyung Kim #include "util/cgroup.h"
63c1a604dfSArnaldo Carvalho de Melo #include "perf.h"
64133dc4c3SIngo Molnar 
653052ba56SArnaldo Carvalho de Melo #include <linux/ctype.h>
66378ef0f5SIan Rogers #ifdef HAVE_LIBTRACEEVENT
67378ef0f5SIan Rogers #include <traceevent/event-parse.h>
68378ef0f5SIan Rogers #endif
693d689ed6SArnaldo Carvalho de Melo 
70133dc4c3SIngo Molnar static char const		*script_name;
71133dc4c3SIngo Molnar static char const		*generate_script_lang;
7290b10f47SAndi Kleen static bool			reltime;
7326567ed7SHagen Paul Pfeifer static bool			deltatime;
7490b10f47SAndi Kleen static u64			initial_time;
7526567ed7SHagen Paul Pfeifer static u64			previous_time;
76133dc4c3SIngo Molnar static bool			debug_mode;
77133dc4c3SIngo Molnar static u64			last_timestamp;
78133dc4c3SIngo Molnar static u64			nr_unordered;
79c0230b2bSDavid Ahern static bool			no_callchain;
8047390ae2SNamhyung Kim static bool			latency_format;
81317df650SRobert Richter static bool			system_wide;
82400ea6d3SAdrian Hunter static bool			print_flags;
835d67be97SAnton Blanchard static const char		*cpu_list;
845d67be97SAnton Blanchard static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
8591a2c3d5SJiri Olsa static struct perf_stat_config	stat_config;
8648d02a1dSAndi Kleen static int			max_blocks;
873ab481a1SAndi Kleen static bool			native_arch;
88291961fcSAdrian Hunter static struct dlfilter		*dlfilter;
893d032a25SAdrian Hunter static int			dlargc;
903d032a25SAdrian Hunter static char			**dlargv;
91133dc4c3SIngo Molnar 
9244cbe729SAdrian Hunter unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
9303cd1fedSAdrian Hunter 
94745f43e3SDavid Ahern enum perf_output_field {
9560e5eeb5SJiri Olsa 	PERF_OUTPUT_COMM            = 1ULL << 0,
9660e5eeb5SJiri Olsa 	PERF_OUTPUT_TID             = 1ULL << 1,
9760e5eeb5SJiri Olsa 	PERF_OUTPUT_PID             = 1ULL << 2,
9860e5eeb5SJiri Olsa 	PERF_OUTPUT_TIME            = 1ULL << 3,
9960e5eeb5SJiri Olsa 	PERF_OUTPUT_CPU             = 1ULL << 4,
10060e5eeb5SJiri Olsa 	PERF_OUTPUT_EVNAME          = 1ULL << 5,
10160e5eeb5SJiri Olsa 	PERF_OUTPUT_TRACE           = 1ULL << 6,
10260e5eeb5SJiri Olsa 	PERF_OUTPUT_IP              = 1ULL << 7,
10360e5eeb5SJiri Olsa 	PERF_OUTPUT_SYM             = 1ULL << 8,
10460e5eeb5SJiri Olsa 	PERF_OUTPUT_DSO             = 1ULL << 9,
10560e5eeb5SJiri Olsa 	PERF_OUTPUT_ADDR            = 1ULL << 10,
10660e5eeb5SJiri Olsa 	PERF_OUTPUT_SYMOFFSET       = 1ULL << 11,
10760e5eeb5SJiri Olsa 	PERF_OUTPUT_SRCLINE         = 1ULL << 12,
10860e5eeb5SJiri Olsa 	PERF_OUTPUT_PERIOD          = 1ULL << 13,
10960e5eeb5SJiri Olsa 	PERF_OUTPUT_IREGS	    = 1ULL << 14,
11060e5eeb5SJiri Olsa 	PERF_OUTPUT_BRSTACK	    = 1ULL << 15,
11160e5eeb5SJiri Olsa 	PERF_OUTPUT_BRSTACKSYM	    = 1ULL << 16,
11260e5eeb5SJiri Olsa 	PERF_OUTPUT_DATA_SRC	    = 1ULL << 17,
11360e5eeb5SJiri Olsa 	PERF_OUTPUT_WEIGHT	    = 1ULL << 18,
11460e5eeb5SJiri Olsa 	PERF_OUTPUT_BPF_OUTPUT	    = 1ULL << 19,
11560e5eeb5SJiri Olsa 	PERF_OUTPUT_CALLINDENT	    = 1ULL << 20,
11660e5eeb5SJiri Olsa 	PERF_OUTPUT_INSN	    = 1ULL << 21,
11760e5eeb5SJiri Olsa 	PERF_OUTPUT_INSNLEN	    = 1ULL << 22,
11860e5eeb5SJiri Olsa 	PERF_OUTPUT_BRSTACKINSN	    = 1ULL << 23,
11960e5eeb5SJiri Olsa 	PERF_OUTPUT_BRSTACKOFF	    = 1ULL << 24,
12060e5eeb5SJiri Olsa 	PERF_OUTPUT_SYNTH           = 1ULL << 25,
12160e5eeb5SJiri Olsa 	PERF_OUTPUT_PHYS_ADDR       = 1ULL << 26,
12260e5eeb5SJiri Olsa 	PERF_OUTPUT_UREGS	    = 1ULL << 27,
12360e5eeb5SJiri Olsa 	PERF_OUTPUT_METRIC	    = 1ULL << 28,
12460e5eeb5SJiri Olsa 	PERF_OUTPUT_MISC            = 1ULL << 29,
12560e5eeb5SJiri Olsa 	PERF_OUTPUT_SRCCODE	    = 1ULL << 30,
12660e5eeb5SJiri Olsa 	PERF_OUTPUT_IPC             = 1ULL << 31,
127e534bfb1SJiri Olsa 	PERF_OUTPUT_TOD             = 1ULL << 32,
1286b9bae63SKan Liang 	PERF_OUTPUT_DATA_PAGE_SIZE  = 1ULL << 33,
129c513de8aSStephane Eranian 	PERF_OUTPUT_CODE_PAGE_SIZE  = 1ULL << 34,
1306ea5d1a3SKan Liang 	PERF_OUTPUT_INS_LAT         = 1ULL << 35,
1316f680c6aSKan Liang 	PERF_OUTPUT_BRSTACKINSNLEN  = 1ULL << 36,
132e28fb159SAdrian Hunter 	PERF_OUTPUT_MACHINE_PID     = 1ULL << 37,
133e28fb159SAdrian Hunter 	PERF_OUTPUT_VCPU            = 1ULL << 38,
1343fd7a168SNamhyung Kim 	PERF_OUTPUT_CGROUP          = 1ULL << 39,
13517f248aaSKan Liang 	PERF_OUTPUT_RETIRE_LAT      = 1ULL << 40,
136af9eb56bSChangbin Du 	PERF_OUTPUT_DSOFF           = 1ULL << 41,
137e534bfb1SJiri Olsa };
138e534bfb1SJiri Olsa 
139e534bfb1SJiri Olsa struct perf_script {
140e534bfb1SJiri Olsa 	struct perf_tool	tool;
141e534bfb1SJiri Olsa 	struct perf_session	*session;
142e534bfb1SJiri Olsa 	bool			show_task_events;
143e534bfb1SJiri Olsa 	bool			show_mmap_events;
144e534bfb1SJiri Olsa 	bool			show_switch_events;
145e534bfb1SJiri Olsa 	bool			show_namespace_events;
146e534bfb1SJiri Olsa 	bool			show_lost_events;
147e534bfb1SJiri Olsa 	bool			show_round_events;
148e534bfb1SJiri Olsa 	bool			show_bpf_events;
149e534bfb1SJiri Olsa 	bool			show_cgroup_events;
150e534bfb1SJiri Olsa 	bool			show_text_poke_events;
151e534bfb1SJiri Olsa 	bool			allocated;
152e534bfb1SJiri Olsa 	bool			per_event_dump;
153e534bfb1SJiri Olsa 	bool			stitch_lbr;
154e534bfb1SJiri Olsa 	struct evswitch		evswitch;
155e534bfb1SJiri Olsa 	struct perf_cpu_map	*cpus;
156e534bfb1SJiri Olsa 	struct perf_thread_map *threads;
157e534bfb1SJiri Olsa 	int			name_width;
158e534bfb1SJiri Olsa 	const char              *time_str;
159e534bfb1SJiri Olsa 	struct perf_time_interval *ptime_range;
160e534bfb1SJiri Olsa 	int			range_size;
161e534bfb1SJiri Olsa 	int			range_num;
162745f43e3SDavid Ahern };
163745f43e3SDavid Ahern 
164745f43e3SDavid Ahern struct output_option {
165745f43e3SDavid Ahern 	const char *str;
166745f43e3SDavid Ahern 	enum perf_output_field field;
167745f43e3SDavid Ahern } all_output_options[] = {
168745f43e3SDavid Ahern 	{.str = "comm",  .field = PERF_OUTPUT_COMM},
169745f43e3SDavid Ahern 	{.str = "tid",   .field = PERF_OUTPUT_TID},
170745f43e3SDavid Ahern 	{.str = "pid",   .field = PERF_OUTPUT_PID},
171745f43e3SDavid Ahern 	{.str = "time",  .field = PERF_OUTPUT_TIME},
172745f43e3SDavid Ahern 	{.str = "cpu",   .field = PERF_OUTPUT_CPU},
173745f43e3SDavid Ahern 	{.str = "event", .field = PERF_OUTPUT_EVNAME},
174745f43e3SDavid Ahern 	{.str = "trace", .field = PERF_OUTPUT_TRACE},
175787bef17SDavid Ahern 	{.str = "ip",    .field = PERF_OUTPUT_IP},
176c0230b2bSDavid Ahern 	{.str = "sym",   .field = PERF_OUTPUT_SYM},
177610723f2SDavid Ahern 	{.str = "dso",   .field = PERF_OUTPUT_DSO},
178af9eb56bSChangbin Du 	{.str = "dsoff", .field = PERF_OUTPUT_DSOFF},
1797cec0922SDavid Ahern 	{.str = "addr",  .field = PERF_OUTPUT_ADDR},
180a978f2abSAkihiro Nagai 	{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
181cc8fae1dSAdrian Hunter 	{.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
182535aeaaeSJiri Olsa 	{.str = "period", .field = PERF_OUTPUT_PERIOD},
183fc36f948SStephane Eranian 	{.str = "iregs", .field = PERF_OUTPUT_IREGS},
184b1491aceSAndi Kleen 	{.str = "uregs", .field = PERF_OUTPUT_UREGS},
185dc323ce8SStephane Eranian 	{.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
186dc323ce8SStephane Eranian 	{.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
18794ddddfaSJiri Olsa 	{.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},
18894ddddfaSJiri Olsa 	{.str = "weight",   .field = PERF_OUTPUT_WEIGHT},
18930372f04SWang Nan 	{.str = "bpf-output",   .field = PERF_OUTPUT_BPF_OUTPUT},
190e216708dSAdrian Hunter 	{.str = "callindent", .field = PERF_OUTPUT_CALLINDENT},
191224e2c97SAndi Kleen 	{.str = "insn", .field = PERF_OUTPUT_INSN},
192224e2c97SAndi Kleen 	{.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},
19348d02a1dSAndi Kleen 	{.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
194106dacd8SMark Santaniello 	{.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
19547e78084SAdrian Hunter 	{.str = "synth", .field = PERF_OUTPUT_SYNTH},
19649d58f04SKan Liang 	{.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
1974bd1bef8SAndi Kleen 	{.str = "metric", .field = PERF_OUTPUT_METRIC},
19828a0b398SJiri Olsa 	{.str = "misc", .field = PERF_OUTPUT_MISC},
199dd2e18e9SAndi Kleen 	{.str = "srccode", .field = PERF_OUTPUT_SRCCODE},
20068fb45bfSAdrian Hunter 	{.str = "ipc", .field = PERF_OUTPUT_IPC},
201e534bfb1SJiri Olsa 	{.str = "tod", .field = PERF_OUTPUT_TOD},
2026b9bae63SKan Liang 	{.str = "data_page_size", .field = PERF_OUTPUT_DATA_PAGE_SIZE},
203c513de8aSStephane Eranian 	{.str = "code_page_size", .field = PERF_OUTPUT_CODE_PAGE_SIZE},
2046ea5d1a3SKan Liang 	{.str = "ins_lat", .field = PERF_OUTPUT_INS_LAT},
2056f680c6aSKan Liang 	{.str = "brstackinsnlen", .field = PERF_OUTPUT_BRSTACKINSNLEN},
206e28fb159SAdrian Hunter 	{.str = "machine_pid", .field = PERF_OUTPUT_MACHINE_PID},
207e28fb159SAdrian Hunter 	{.str = "vcpu", .field = PERF_OUTPUT_VCPU},
2083fd7a168SNamhyung Kim 	{.str = "cgroup", .field = PERF_OUTPUT_CGROUP},
20917f248aaSKan Liang 	{.str = "retire_lat", .field = PERF_OUTPUT_RETIRE_LAT},
210745f43e3SDavid Ahern };
211745f43e3SDavid Ahern 
2121405720dSAdrian Hunter enum {
2131405720dSAdrian Hunter 	OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,
2148adc0a06SJin Yao 	OUTPUT_TYPE_OTHER,
2151405720dSAdrian Hunter 	OUTPUT_TYPE_MAX
2161405720dSAdrian Hunter };
2171405720dSAdrian Hunter 
218745f43e3SDavid Ahern /* default set to maintain compatibility with current format */
2192c9e45f7SDavid Ahern static struct {
2202c9e45f7SDavid Ahern 	bool user_set;
2219cbdb702SDavid Ahern 	bool wildcard_set;
222a6ffaf91SDavid Ahern 	unsigned int print_ip_opts;
2232c9e45f7SDavid Ahern 	u64 fields;
2242c9e45f7SDavid Ahern 	u64 invalid_fields;
2254b6ac811SAndi Kleen 	u64 user_set_fields;
226b5164085SAdrian Hunter 	u64 user_unset_fields;
2271405720dSAdrian Hunter } output[OUTPUT_TYPE_MAX] = {
2282c9e45f7SDavid Ahern 
2292c9e45f7SDavid Ahern 	[PERF_TYPE_HARDWARE] = {
2302c9e45f7SDavid Ahern 		.user_set = false,
2312c9e45f7SDavid Ahern 
2322c9e45f7SDavid Ahern 		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
2332c9e45f7SDavid Ahern 			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
234787bef17SDavid Ahern 			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
2357903a708SSandipan Das 			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
2367903a708SSandipan Das 			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
2371424dc96SDavid Ahern 
23830372f04SWang Nan 		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
2392c9e45f7SDavid Ahern 	},
2402c9e45f7SDavid Ahern 
2412c9e45f7SDavid Ahern 	[PERF_TYPE_SOFTWARE] = {
2422c9e45f7SDavid Ahern 		.user_set = false,
2432c9e45f7SDavid Ahern 
2442c9e45f7SDavid Ahern 		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
2452c9e45f7SDavid Ahern 			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
246787bef17SDavid Ahern 			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
2477903a708SSandipan Das 			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
2487903a708SSandipan Das 			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
2497903a708SSandipan Das 			      PERF_OUTPUT_BPF_OUTPUT,
2501424dc96SDavid Ahern 
2512c9e45f7SDavid Ahern 		.invalid_fields = PERF_OUTPUT_TRACE,
2522c9e45f7SDavid Ahern 	},
2532c9e45f7SDavid Ahern 
2542c9e45f7SDavid Ahern 	[PERF_TYPE_TRACEPOINT] = {
2552c9e45f7SDavid Ahern 		.user_set = false,
2562c9e45f7SDavid Ahern 
2572c9e45f7SDavid Ahern 		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
2582c9e45f7SDavid Ahern 				  PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
25930372f04SWang Nan 				  PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE
2602c9e45f7SDavid Ahern 	},
2610817a6a3SArun Sharma 
262fad76d43SSeeteena Thoufeek 	[PERF_TYPE_HW_CACHE] = {
263fad76d43SSeeteena Thoufeek 		.user_set = false,
264fad76d43SSeeteena Thoufeek 
265fad76d43SSeeteena Thoufeek 		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
266fad76d43SSeeteena Thoufeek 			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
267fad76d43SSeeteena Thoufeek 			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
268fad76d43SSeeteena Thoufeek 			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
269fad76d43SSeeteena Thoufeek 			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
270fad76d43SSeeteena Thoufeek 
271fad76d43SSeeteena Thoufeek 		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
272fad76d43SSeeteena Thoufeek 	},
273fad76d43SSeeteena Thoufeek 
2740817a6a3SArun Sharma 	[PERF_TYPE_RAW] = {
2750817a6a3SArun Sharma 		.user_set = false,
2760817a6a3SArun Sharma 
2770817a6a3SArun Sharma 		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
2780817a6a3SArun Sharma 			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
279787bef17SDavid Ahern 			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
2807903a708SSandipan Das 			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
2817903a708SSandipan Das 			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
2827903a708SSandipan Das 			      PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC |
2836b9bae63SKan Liang 			      PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR |
2846ea5d1a3SKan Liang 			      PERF_OUTPUT_DATA_PAGE_SIZE | PERF_OUTPUT_CODE_PAGE_SIZE |
28517f248aaSKan Liang 			      PERF_OUTPUT_INS_LAT | PERF_OUTPUT_RETIRE_LAT,
2860817a6a3SArun Sharma 
28730372f04SWang Nan 		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
2880817a6a3SArun Sharma 	},
28927cfef00SWang Nan 
29027cfef00SWang Nan 	[PERF_TYPE_BREAKPOINT] = {
29127cfef00SWang Nan 		.user_set = false,
29227cfef00SWang Nan 
29327cfef00SWang Nan 		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
29427cfef00SWang Nan 			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
29527cfef00SWang Nan 			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
2967903a708SSandipan Das 			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
2977903a708SSandipan Das 			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
29827cfef00SWang Nan 
29930372f04SWang Nan 		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
30027cfef00SWang Nan 	},
3011405720dSAdrian Hunter 
3021405720dSAdrian Hunter 	[OUTPUT_TYPE_SYNTH] = {
3031405720dSAdrian Hunter 		.user_set = false,
3041405720dSAdrian Hunter 
3051405720dSAdrian Hunter 		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
3061405720dSAdrian Hunter 			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
3071405720dSAdrian Hunter 			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
3087903a708SSandipan Das 			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
3097903a708SSandipan Das 			      PERF_OUTPUT_DSO | PERF_OUTPUT_SYNTH,
3101405720dSAdrian Hunter 
3111405720dSAdrian Hunter 		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
3121405720dSAdrian Hunter 	},
3138adc0a06SJin Yao 
3148adc0a06SJin Yao 	[OUTPUT_TYPE_OTHER] = {
3158adc0a06SJin Yao 		.user_set = false,
3168adc0a06SJin Yao 
3178adc0a06SJin Yao 		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
3188adc0a06SJin Yao 			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
3198adc0a06SJin Yao 			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
3208adc0a06SJin Yao 			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
3218adc0a06SJin Yao 			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
3228adc0a06SJin Yao 
3238adc0a06SJin Yao 		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
3248adc0a06SJin Yao 	},
3251424dc96SDavid Ahern };
326745f43e3SDavid Ahern 
32732dcd021SJiri Olsa struct evsel_script {
328642ee1c6SArnaldo Carvalho de Melo        char *filename;
329642ee1c6SArnaldo Carvalho de Melo        FILE *fp;
330642ee1c6SArnaldo Carvalho de Melo        u64  samples;
3314bd1bef8SAndi Kleen        /* For metric output */
3324bd1bef8SAndi Kleen        u64  val;
3334bd1bef8SAndi Kleen        int  gnum;
334642ee1c6SArnaldo Carvalho de Melo };
335642ee1c6SArnaldo Carvalho de Melo 
evsel_script(struct evsel * evsel)33632dcd021SJiri Olsa static inline struct evsel_script *evsel_script(struct evsel *evsel)
3374bd1bef8SAndi Kleen {
33832dcd021SJiri Olsa 	return (struct evsel_script *)evsel->priv;
3394bd1bef8SAndi Kleen }
3404bd1bef8SAndi Kleen 
evsel_script__new(struct evsel * evsel,struct perf_data * data)341297e69bfSArnaldo Carvalho de Melo static struct evsel_script *evsel_script__new(struct evsel *evsel, struct perf_data *data)
342642ee1c6SArnaldo Carvalho de Melo {
34332dcd021SJiri Olsa 	struct evsel_script *es = zalloc(sizeof(*es));
344642ee1c6SArnaldo Carvalho de Melo 
345642ee1c6SArnaldo Carvalho de Melo 	if (es != NULL) {
3468ab2e96dSArnaldo Carvalho de Melo 		if (asprintf(&es->filename, "%s.%s.dump", data->file.path, evsel__name(evsel)) < 0)
347642ee1c6SArnaldo Carvalho de Melo 			goto out_free;
348642ee1c6SArnaldo Carvalho de Melo 		es->fp = fopen(es->filename, "w");
349642ee1c6SArnaldo Carvalho de Melo 		if (es->fp == NULL)
350642ee1c6SArnaldo Carvalho de Melo 			goto out_free_filename;
351642ee1c6SArnaldo Carvalho de Melo 	}
352642ee1c6SArnaldo Carvalho de Melo 
353642ee1c6SArnaldo Carvalho de Melo 	return es;
354642ee1c6SArnaldo Carvalho de Melo out_free_filename:
355642ee1c6SArnaldo Carvalho de Melo 	zfree(&es->filename);
356642ee1c6SArnaldo Carvalho de Melo out_free:
357642ee1c6SArnaldo Carvalho de Melo 	free(es);
358642ee1c6SArnaldo Carvalho de Melo 	return NULL;
359642ee1c6SArnaldo Carvalho de Melo }
360642ee1c6SArnaldo Carvalho de Melo 
evsel_script__delete(struct evsel_script * es)361297e69bfSArnaldo Carvalho de Melo static void evsel_script__delete(struct evsel_script *es)
362642ee1c6SArnaldo Carvalho de Melo {
363642ee1c6SArnaldo Carvalho de Melo 	zfree(&es->filename);
364642ee1c6SArnaldo Carvalho de Melo 	fclose(es->fp);
365642ee1c6SArnaldo Carvalho de Melo 	es->fp = NULL;
366642ee1c6SArnaldo Carvalho de Melo 	free(es);
367642ee1c6SArnaldo Carvalho de Melo }
368642ee1c6SArnaldo Carvalho de Melo 
evsel_script__fprintf(struct evsel_script * es,FILE * fp)369297e69bfSArnaldo Carvalho de Melo static int evsel_script__fprintf(struct evsel_script *es, FILE *fp)
370642ee1c6SArnaldo Carvalho de Melo {
371642ee1c6SArnaldo Carvalho de Melo 	struct stat st;
372642ee1c6SArnaldo Carvalho de Melo 
373642ee1c6SArnaldo Carvalho de Melo 	fstat(fileno(es->fp), &st);
374642ee1c6SArnaldo Carvalho de Melo 	return fprintf(fp, "[ perf script: Wrote %.3f MB %s (%" PRIu64 " samples) ]\n",
375642ee1c6SArnaldo Carvalho de Melo 		       st.st_size / 1024.0 / 1024.0, es->filename, es->samples);
376642ee1c6SArnaldo Carvalho de Melo }
377642ee1c6SArnaldo Carvalho de Melo 
output_type(unsigned int type)3781405720dSAdrian Hunter static inline int output_type(unsigned int type)
3791405720dSAdrian Hunter {
3801405720dSAdrian Hunter 	switch (type) {
3811405720dSAdrian Hunter 	case PERF_TYPE_SYNTH:
3821405720dSAdrian Hunter 		return OUTPUT_TYPE_SYNTH;
3831405720dSAdrian Hunter 	default:
3848adc0a06SJin Yao 		if (type < PERF_TYPE_MAX)
3851405720dSAdrian Hunter 			return type;
3861405720dSAdrian Hunter 	}
3878adc0a06SJin Yao 
3888adc0a06SJin Yao 	return OUTPUT_TYPE_OTHER;
3891405720dSAdrian Hunter }
3901405720dSAdrian Hunter 
output_set_by_user(void)3912c9e45f7SDavid Ahern static bool output_set_by_user(void)
3922c9e45f7SDavid Ahern {
3932c9e45f7SDavid Ahern 	int j;
3941405720dSAdrian Hunter 	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
3952c9e45f7SDavid Ahern 		if (output[j].user_set)
3962c9e45f7SDavid Ahern 			return true;
3972c9e45f7SDavid Ahern 	}
3982c9e45f7SDavid Ahern 	return false;
3992c9e45f7SDavid Ahern }
400745f43e3SDavid Ahern 
output_field2str(enum perf_output_field field)4019cbdb702SDavid Ahern static const char *output_field2str(enum perf_output_field field)
4029cbdb702SDavid Ahern {
4039cbdb702SDavid Ahern 	int i, imax = ARRAY_SIZE(all_output_options);
4049cbdb702SDavid Ahern 	const char *str = "";
4059cbdb702SDavid Ahern 
4069cbdb702SDavid Ahern 	for (i = 0; i < imax; ++i) {
4079cbdb702SDavid Ahern 		if (all_output_options[i].field == field) {
4089cbdb702SDavid Ahern 			str = all_output_options[i].str;
4099cbdb702SDavid Ahern 			break;
4109cbdb702SDavid Ahern 		}
4119cbdb702SDavid Ahern 	}
4129cbdb702SDavid Ahern 	return str;
4139cbdb702SDavid Ahern }
4149cbdb702SDavid Ahern 
4151405720dSAdrian Hunter #define PRINT_FIELD(x)  (output[output_type(attr->type)].fields & PERF_OUTPUT_##x)
4161424dc96SDavid Ahern 
evsel__do_check_stype(struct evsel * evsel,u64 sample_type,const char * sample_msg,enum perf_output_field field,bool allow_user_set)417ec98b6dfSArnaldo Carvalho de Melo static int evsel__do_check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
418ec98b6dfSArnaldo Carvalho de Melo 				 enum perf_output_field field, bool allow_user_set)
4191424dc96SDavid Ahern {
4201fc632ceSJiri Olsa 	struct perf_event_attr *attr = &evsel->core.attr;
4211405720dSAdrian Hunter 	int type = output_type(attr->type);
4229cbdb702SDavid Ahern 	const char *evname;
4239cbdb702SDavid Ahern 
4249cbdb702SDavid Ahern 	if (attr->sample_type & sample_type)
4259cbdb702SDavid Ahern 		return 0;
4269cbdb702SDavid Ahern 
4274b6ac811SAndi Kleen 	if (output[type].user_set_fields & field) {
4286d5cdd64SAdrian Hunter 		if (allow_user_set)
4296d5cdd64SAdrian Hunter 			return 0;
4308ab2e96dSArnaldo Carvalho de Melo 		evname = evsel__name(evsel);
4319cbdb702SDavid Ahern 		pr_err("Samples for '%s' event do not have %s attribute set. "
4329cbdb702SDavid Ahern 		       "Cannot print '%s' field.\n",
4339cbdb702SDavid Ahern 		       evname, sample_msg, output_field2str(field));
4349cbdb702SDavid Ahern 		return -1;
4359cbdb702SDavid Ahern 	}
4369cbdb702SDavid Ahern 
4379cbdb702SDavid Ahern 	/* user did not ask for it explicitly so remove from the default list */
4389cbdb702SDavid Ahern 	output[type].fields &= ~field;
4398ab2e96dSArnaldo Carvalho de Melo 	evname = evsel__name(evsel);
4409cbdb702SDavid Ahern 	pr_debug("Samples for '%s' event do not have %s attribute set. "
4419cbdb702SDavid Ahern 		 "Skipping '%s' field.\n",
4429cbdb702SDavid Ahern 		 evname, sample_msg, output_field2str(field));
4439cbdb702SDavid Ahern 
4449cbdb702SDavid Ahern 	return 0;
4459cbdb702SDavid Ahern }
4469cbdb702SDavid Ahern 
evsel__check_stype(struct evsel * evsel,u64 sample_type,const char * sample_msg,enum perf_output_field field)447ec98b6dfSArnaldo Carvalho de Melo static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
4486d5cdd64SAdrian Hunter 			      enum perf_output_field field)
4496d5cdd64SAdrian Hunter {
450ec98b6dfSArnaldo Carvalho de Melo 	return evsel__do_check_stype(evsel, sample_type, sample_msg, field, false);
4516d5cdd64SAdrian Hunter }
4526d5cdd64SAdrian Hunter 
evsel__check_attr(struct evsel * evsel,struct perf_session * session)453afdd63f5SArnaldo Carvalho de Melo static int evsel__check_attr(struct evsel *evsel, struct perf_session *session)
4549cbdb702SDavid Ahern {
4551fc632ceSJiri Olsa 	struct perf_event_attr *attr = &evsel->core.attr;
4566d5cdd64SAdrian Hunter 	bool allow_user_set;
4576d5cdd64SAdrian Hunter 
45882b2425fSZhengjun Xing 	if (evsel__is_dummy_event(evsel))
45982b2425fSZhengjun Xing 		return 0;
46082b2425fSZhengjun Xing 
461e099eba8SJiri Olsa 	if (perf_header__has_feat(&session->header, HEADER_STAT))
462e099eba8SJiri Olsa 		return 0;
463e099eba8SJiri Olsa 
4646d5cdd64SAdrian Hunter 	allow_user_set = perf_header__has_feat(&session->header,
4656d5cdd64SAdrian Hunter 					       HEADER_AUXTRACE);
4669cbdb702SDavid Ahern 
4671424dc96SDavid Ahern 	if (PRINT_FIELD(TRACE) &&
4681424dc96SDavid Ahern 	    !perf_session__has_traces(session, "record -R"))
4691424dc96SDavid Ahern 		return -EINVAL;
4701424dc96SDavid Ahern 
471787bef17SDavid Ahern 	if (PRINT_FIELD(IP)) {
472ec98b6dfSArnaldo Carvalho de Melo 		if (evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", PERF_OUTPUT_IP))
4731424dc96SDavid Ahern 			return -EINVAL;
4741424dc96SDavid Ahern 	}
4757cec0922SDavid Ahern 
4767cec0922SDavid Ahern 	if (PRINT_FIELD(ADDR) &&
477ec98b6dfSArnaldo Carvalho de Melo 	    evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", PERF_OUTPUT_ADDR, allow_user_set))
4787cec0922SDavid Ahern 		return -EINVAL;
4797cec0922SDavid Ahern 
48094ddddfaSJiri Olsa 	if (PRINT_FIELD(DATA_SRC) &&
481c6d8df01SLeo Yan 	    evsel__do_check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC", PERF_OUTPUT_DATA_SRC, allow_user_set))
48294ddddfaSJiri Olsa 		return -EINVAL;
48394ddddfaSJiri Olsa 
48494ddddfaSJiri Olsa 	if (PRINT_FIELD(WEIGHT) &&
48513e741b8SGerman Gomez 	    evsel__do_check_stype(evsel, PERF_SAMPLE_WEIGHT_TYPE, "WEIGHT", PERF_OUTPUT_WEIGHT, allow_user_set))
48694ddddfaSJiri Olsa 		return -EINVAL;
48794ddddfaSJiri Olsa 
48837fed3deSAndi Kleen 	if (PRINT_FIELD(SYM) &&
4891fc632ceSJiri Olsa 	    !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
4907cec0922SDavid Ahern 		pr_err("Display of symbols requested but neither sample IP nor "
49137fed3deSAndi Kleen 			   "sample address\navailable. Hence, no addresses to convert "
4927cec0922SDavid Ahern 		       "to symbols.\n");
493787bef17SDavid Ahern 		return -EINVAL;
494787bef17SDavid Ahern 	}
495a978f2abSAkihiro Nagai 	if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
496a978f2abSAkihiro Nagai 		pr_err("Display of offsets requested but symbol is not"
497a978f2abSAkihiro Nagai 		       "selected.\n");
498a978f2abSAkihiro Nagai 		return -EINVAL;
499a978f2abSAkihiro Nagai 	}
50037fed3deSAndi Kleen 	if (PRINT_FIELD(DSO) &&
5011fc632ceSJiri Olsa 	    !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
50237fed3deSAndi Kleen 		pr_err("Display of DSO requested but no address to convert.\n");
503610723f2SDavid Ahern 		return -EINVAL;
504610723f2SDavid Ahern 	}
505dd2e18e9SAndi Kleen 	if ((PRINT_FIELD(SRCLINE) || PRINT_FIELD(SRCCODE)) && !PRINT_FIELD(IP)) {
506cc8fae1dSAdrian Hunter 		pr_err("Display of source line number requested but sample IP is not\n"
507cc8fae1dSAdrian Hunter 		       "selected. Hence, no address to lookup the source line number.\n");
508cc8fae1dSAdrian Hunter 		return -EINVAL;
509cc8fae1dSAdrian Hunter 	}
5106f680c6aSKan Liang 	if ((PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN)) && !allow_user_set &&
51192c7d7cdSArnaldo Carvalho de Melo 	    !(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY)) {
51248d02a1dSAndi Kleen 		pr_err("Display of branch stack assembler requested, but non all-branch filter set\n"
51348d02a1dSAndi Kleen 		       "Hint: run 'perf record -b ...'\n");
51448d02a1dSAndi Kleen 		return -EINVAL;
51548d02a1dSAndi Kleen 	}
5161424dc96SDavid Ahern 	if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
517ec98b6dfSArnaldo Carvalho de Melo 	    evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", PERF_OUTPUT_TID|PERF_OUTPUT_PID))
5181424dc96SDavid Ahern 		return -EINVAL;
5191424dc96SDavid Ahern 
5201424dc96SDavid Ahern 	if (PRINT_FIELD(TIME) &&
521ec98b6dfSArnaldo Carvalho de Melo 	    evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", PERF_OUTPUT_TIME))
5221424dc96SDavid Ahern 		return -EINVAL;
5231424dc96SDavid Ahern 
5241424dc96SDavid Ahern 	if (PRINT_FIELD(CPU) &&
525ec98b6dfSArnaldo Carvalho de Melo 	    evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU", PERF_OUTPUT_CPU, allow_user_set))
5261424dc96SDavid Ahern 		return -EINVAL;
5279cbdb702SDavid Ahern 
528fc36f948SStephane Eranian 	if (PRINT_FIELD(IREGS) &&
529add07ccdSAdrian Hunter 	    evsel__do_check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", PERF_OUTPUT_IREGS, allow_user_set))
530fc36f948SStephane Eranian 		return -EINVAL;
531fc36f948SStephane Eranian 
532b1491aceSAndi Kleen 	if (PRINT_FIELD(UREGS) &&
533ec98b6dfSArnaldo Carvalho de Melo 	    evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS", PERF_OUTPUT_UREGS))
534b1491aceSAndi Kleen 		return -EINVAL;
535b1491aceSAndi Kleen 
53649d58f04SKan Liang 	if (PRINT_FIELD(PHYS_ADDR) &&
5379edcde68SYao Jin 	    evsel__do_check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", PERF_OUTPUT_PHYS_ADDR, allow_user_set))
53849d58f04SKan Liang 		return -EINVAL;
53949d58f04SKan Liang 
5406b9bae63SKan Liang 	if (PRINT_FIELD(DATA_PAGE_SIZE) &&
5416b9bae63SKan Liang 	    evsel__check_stype(evsel, PERF_SAMPLE_DATA_PAGE_SIZE, "DATA_PAGE_SIZE", PERF_OUTPUT_DATA_PAGE_SIZE))
5426b9bae63SKan Liang 		return -EINVAL;
5436b9bae63SKan Liang 
544c513de8aSStephane Eranian 	if (PRINT_FIELD(CODE_PAGE_SIZE) &&
545c513de8aSStephane Eranian 	    evsel__check_stype(evsel, PERF_SAMPLE_CODE_PAGE_SIZE, "CODE_PAGE_SIZE", PERF_OUTPUT_CODE_PAGE_SIZE))
546c513de8aSStephane Eranian 		return -EINVAL;
547c513de8aSStephane Eranian 
5486ea5d1a3SKan Liang 	if (PRINT_FIELD(INS_LAT) &&
5496ea5d1a3SKan Liang 	    evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT_STRUCT, "WEIGHT_STRUCT", PERF_OUTPUT_INS_LAT))
5506ea5d1a3SKan Liang 		return -EINVAL;
5516ea5d1a3SKan Liang 
5523fd7a168SNamhyung Kim 	if (PRINT_FIELD(CGROUP) &&
5533fd7a168SNamhyung Kim 	    evsel__check_stype(evsel, PERF_SAMPLE_CGROUP, "CGROUP", PERF_OUTPUT_CGROUP)) {
5543fd7a168SNamhyung Kim 		pr_err("Hint: run 'perf record --all-cgroups ...'\n");
5553fd7a168SNamhyung Kim 		return -EINVAL;
5563fd7a168SNamhyung Kim 	}
5573fd7a168SNamhyung Kim 
55817f248aaSKan Liang 	if (PRINT_FIELD(RETIRE_LAT) &&
55917f248aaSKan Liang 	    evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT_STRUCT, "WEIGHT_STRUCT", PERF_OUTPUT_RETIRE_LAT))
56017f248aaSKan Liang 		return -EINVAL;
56117f248aaSKan Liang 
5629cbdb702SDavid Ahern 	return 0;
5639cbdb702SDavid Ahern }
5649cbdb702SDavid Ahern 
set_print_ip_opts(struct perf_event_attr * attr)5657ea95727SAdrian Hunter static void set_print_ip_opts(struct perf_event_attr *attr)
5667ea95727SAdrian Hunter {
5671405720dSAdrian Hunter 	unsigned int type = output_type(attr->type);
5687ea95727SAdrian Hunter 
5697ea95727SAdrian Hunter 	output[type].print_ip_opts = 0;
5707ea95727SAdrian Hunter 	if (PRINT_FIELD(IP))
571e20ab86eSArnaldo Carvalho de Melo 		output[type].print_ip_opts |= EVSEL__PRINT_IP;
5727ea95727SAdrian Hunter 
5737ea95727SAdrian Hunter 	if (PRINT_FIELD(SYM))
574e20ab86eSArnaldo Carvalho de Melo 		output[type].print_ip_opts |= EVSEL__PRINT_SYM;
5757ea95727SAdrian Hunter 
5767ea95727SAdrian Hunter 	if (PRINT_FIELD(DSO))
577e20ab86eSArnaldo Carvalho de Melo 		output[type].print_ip_opts |= EVSEL__PRINT_DSO;
5787ea95727SAdrian Hunter 
579af9eb56bSChangbin Du 	if (PRINT_FIELD(DSOFF))
580af9eb56bSChangbin Du 		output[type].print_ip_opts |= EVSEL__PRINT_DSOFF;
581af9eb56bSChangbin Du 
5827ea95727SAdrian Hunter 	if (PRINT_FIELD(SYMOFFSET))
583e20ab86eSArnaldo Carvalho de Melo 		output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET;
584cc8fae1dSAdrian Hunter 
585cc8fae1dSAdrian Hunter 	if (PRINT_FIELD(SRCLINE))
586e20ab86eSArnaldo Carvalho de Melo 		output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
5877ea95727SAdrian Hunter }
5887ea95727SAdrian Hunter 
find_first_output_type(struct evlist * evlist,unsigned int type)589ff6f41fbSAdrian Hunter static struct evsel *find_first_output_type(struct evlist *evlist,
590ff6f41fbSAdrian Hunter 					    unsigned int type)
591ff6f41fbSAdrian Hunter {
592ff6f41fbSAdrian Hunter 	struct evsel *evsel;
593ff6f41fbSAdrian Hunter 
594ff6f41fbSAdrian Hunter 	evlist__for_each_entry(evlist, evsel) {
59535503ce1SJiri Olsa 		if (evsel__is_dummy_event(evsel))
59635503ce1SJiri Olsa 			continue;
597ff6f41fbSAdrian Hunter 		if (output_type(evsel->core.attr.type) == (int)type)
598ff6f41fbSAdrian Hunter 			return evsel;
599ff6f41fbSAdrian Hunter 	}
600ff6f41fbSAdrian Hunter 	return NULL;
601ff6f41fbSAdrian Hunter }
602ff6f41fbSAdrian Hunter 
6039cbdb702SDavid Ahern /*
6049cbdb702SDavid Ahern  * verify all user requested events exist and the samples
6059cbdb702SDavid Ahern  * have the expected data
6069cbdb702SDavid Ahern  */
perf_session__check_output_opt(struct perf_session * session)6079cbdb702SDavid Ahern static int perf_session__check_output_opt(struct perf_session *session)
6089cbdb702SDavid Ahern {
609e534bfb1SJiri Olsa 	bool tod = false;
61040f20e50SHe Kuang 	unsigned int j;
61132dcd021SJiri Olsa 	struct evsel *evsel;
6129cbdb702SDavid Ahern 
6131405720dSAdrian Hunter 	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
614ff6f41fbSAdrian Hunter 		evsel = find_first_output_type(session->evlist, j);
6159cbdb702SDavid Ahern 
6169cbdb702SDavid Ahern 		/*
6179cbdb702SDavid Ahern 		 * even if fields is set to 0 (ie., show nothing) event must
6189cbdb702SDavid Ahern 		 * exist if user explicitly includes it on the command line
6199cbdb702SDavid Ahern 		 */
6201405720dSAdrian Hunter 		if (!evsel && output[j].user_set && !output[j].wildcard_set &&
6211405720dSAdrian Hunter 		    j != OUTPUT_TYPE_SYNTH) {
6229cbdb702SDavid Ahern 			pr_err("%s events do not exist. "
623701516aeSAdrian Hunter 			       "Remove corresponding -F option to proceed.\n",
6249cbdb702SDavid Ahern 			       event_type(j));
6259cbdb702SDavid Ahern 			return -1;
6269cbdb702SDavid Ahern 		}
6279cbdb702SDavid Ahern 
6289cbdb702SDavid Ahern 		if (evsel && output[j].fields &&
629afdd63f5SArnaldo Carvalho de Melo 			evsel__check_attr(evsel, session))
6309cbdb702SDavid Ahern 			return -1;
631a6ffaf91SDavid Ahern 
632a6ffaf91SDavid Ahern 		if (evsel == NULL)
633a6ffaf91SDavid Ahern 			continue;
634a6ffaf91SDavid Ahern 
635af9eb56bSChangbin Du 		/* 'dsoff' implys 'dso' field */
636af9eb56bSChangbin Du 		if (output[j].fields & PERF_OUTPUT_DSOFF)
637af9eb56bSChangbin Du 			output[j].fields |= PERF_OUTPUT_DSO;
638af9eb56bSChangbin Du 
6391fc632ceSJiri Olsa 		set_print_ip_opts(&evsel->core.attr);
640e534bfb1SJiri Olsa 		tod |= output[j].fields & PERF_OUTPUT_TOD;
6411424dc96SDavid Ahern 	}
6421424dc96SDavid Ahern 
64398526ee7SAdrian Hunter 	if (!no_callchain) {
64498526ee7SAdrian Hunter 		bool use_callchain = false;
64571ac899bSHe Kuang 		bool not_pipe = false;
64698526ee7SAdrian Hunter 
647e5cadb93SArnaldo Carvalho de Melo 		evlist__for_each_entry(session->evlist, evsel) {
64871ac899bSHe Kuang 			not_pipe = true;
64927de9b2bSArnaldo Carvalho de Melo 			if (evsel__has_callchain(evsel)) {
65098526ee7SAdrian Hunter 				use_callchain = true;
65198526ee7SAdrian Hunter 				break;
65298526ee7SAdrian Hunter 			}
65398526ee7SAdrian Hunter 		}
65471ac899bSHe Kuang 		if (not_pipe && !use_callchain)
65598526ee7SAdrian Hunter 			symbol_conf.use_callchain = false;
65698526ee7SAdrian Hunter 	}
65798526ee7SAdrian Hunter 
65880b8b496SDavid Ahern 	/*
65980b8b496SDavid Ahern 	 * set default for tracepoints to print symbols only
66080b8b496SDavid Ahern 	 * if callchains are present
66180b8b496SDavid Ahern 	 */
66280b8b496SDavid Ahern 	if (symbol_conf.use_callchain &&
66380b8b496SDavid Ahern 	    !output[PERF_TYPE_TRACEPOINT].user_set) {
66480b8b496SDavid Ahern 		j = PERF_TYPE_TRACEPOINT;
66540f20e50SHe Kuang 
666e5cadb93SArnaldo Carvalho de Melo 		evlist__for_each_entry(session->evlist, evsel) {
6671fc632ceSJiri Olsa 			if (evsel->core.attr.type != j)
66840f20e50SHe Kuang 				continue;
66980b8b496SDavid Ahern 
67027de9b2bSArnaldo Carvalho de Melo 			if (evsel__has_callchain(evsel)) {
67180b8b496SDavid Ahern 				output[j].fields |= PERF_OUTPUT_IP;
67280b8b496SDavid Ahern 				output[j].fields |= PERF_OUTPUT_SYM;
6737903a708SSandipan Das 				output[j].fields |= PERF_OUTPUT_SYMOFFSET;
67480b8b496SDavid Ahern 				output[j].fields |= PERF_OUTPUT_DSO;
6751fc632ceSJiri Olsa 				set_print_ip_opts(&evsel->core.attr);
67640f20e50SHe Kuang 				goto out;
67740f20e50SHe Kuang 			}
67880b8b496SDavid Ahern 		}
67980b8b496SDavid Ahern 	}
68080b8b496SDavid Ahern 
681e534bfb1SJiri Olsa 	if (tod && !session->header.env.clock.enabled) {
682e534bfb1SJiri Olsa 		pr_err("Can't provide 'tod' time, missing clock data. "
683e534bfb1SJiri Olsa 		       "Please record with -k/--clockid option.\n");
684e534bfb1SJiri Olsa 		return -1;
685e534bfb1SJiri Olsa 	}
68680b8b496SDavid Ahern out:
6871424dc96SDavid Ahern 	return 0;
6881424dc96SDavid Ahern }
689745f43e3SDavid Ahern 
perf_sample__fprintf_regs(struct regs_dump * regs,uint64_t mask,const char * arch,FILE * fp)69083869019SGerman Gomez static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, const char *arch,
691e534bfb1SJiri Olsa 				     FILE *fp)
692fc36f948SStephane Eranian {
693b1491aceSAndi Kleen 	unsigned i = 0, r;
694a1a58707SArnaldo Carvalho de Melo 	int printed = 0;
695b1491aceSAndi Kleen 
696b1491aceSAndi Kleen 	if (!regs || !regs->regs)
697a1a58707SArnaldo Carvalho de Melo 		return 0;
698b1491aceSAndi Kleen 
699a1a58707SArnaldo Carvalho de Melo 	printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi);
700b1491aceSAndi Kleen 
701b1491aceSAndi Kleen 	for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
702b1491aceSAndi Kleen 		u64 val = regs->regs[i++];
70383869019SGerman Gomez 		printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r, arch), val);
704b1491aceSAndi Kleen 	}
705b1491aceSAndi Kleen 
706a1a58707SArnaldo Carvalho de Melo 	return printed;
707a1a58707SArnaldo Carvalho de Melo }
708a1a58707SArnaldo Carvalho de Melo 
709e534bfb1SJiri Olsa #define DEFAULT_TOD_FMT "%F %H:%M:%S"
710e534bfb1SJiri Olsa 
711e534bfb1SJiri Olsa static char*
tod_scnprintf(struct perf_script * script,char * buf,int buflen,u64 timestamp)712e534bfb1SJiri Olsa tod_scnprintf(struct perf_script *script, char *buf, int buflen,
713e534bfb1SJiri Olsa 	     u64 timestamp)
714e534bfb1SJiri Olsa {
715e534bfb1SJiri Olsa 	u64 tod_ns, clockid_ns;
716e534bfb1SJiri Olsa 	struct perf_env *env;
717e534bfb1SJiri Olsa 	unsigned long nsec;
718e534bfb1SJiri Olsa 	struct tm ltime;
719e534bfb1SJiri Olsa 	char date[64];
720e534bfb1SJiri Olsa 	time_t sec;
721e534bfb1SJiri Olsa 
722e534bfb1SJiri Olsa 	buf[0] = '\0';
723e534bfb1SJiri Olsa 	if (buflen < 64 || !script)
724e534bfb1SJiri Olsa 		return buf;
725e534bfb1SJiri Olsa 
726e534bfb1SJiri Olsa 	env = &script->session->header.env;
727e534bfb1SJiri Olsa 	if (!env->clock.enabled) {
728e534bfb1SJiri Olsa 		scnprintf(buf, buflen, "disabled");
729e534bfb1SJiri Olsa 		return buf;
730e534bfb1SJiri Olsa 	}
731e534bfb1SJiri Olsa 
732e534bfb1SJiri Olsa 	clockid_ns = env->clock.clockid_ns;
733e534bfb1SJiri Olsa 	tod_ns     = env->clock.tod_ns;
734e534bfb1SJiri Olsa 
735e534bfb1SJiri Olsa 	if (timestamp > clockid_ns)
736e534bfb1SJiri Olsa 		tod_ns += timestamp - clockid_ns;
737e534bfb1SJiri Olsa 	else
738e534bfb1SJiri Olsa 		tod_ns -= clockid_ns - timestamp;
739e534bfb1SJiri Olsa 
740e534bfb1SJiri Olsa 	sec  = (time_t) (tod_ns / NSEC_PER_SEC);
741e534bfb1SJiri Olsa 	nsec = tod_ns - sec * NSEC_PER_SEC;
742e534bfb1SJiri Olsa 
743e534bfb1SJiri Olsa 	if (localtime_r(&sec, &ltime) == NULL) {
744e534bfb1SJiri Olsa 		scnprintf(buf, buflen, "failed");
745e534bfb1SJiri Olsa 	} else {
746e534bfb1SJiri Olsa 		strftime(date, sizeof(date), DEFAULT_TOD_FMT, &ltime);
747e534bfb1SJiri Olsa 
748e534bfb1SJiri Olsa 		if (symbol_conf.nanosecs) {
749e534bfb1SJiri Olsa 			snprintf(buf, buflen, "%s.%09lu", date, nsec);
750e534bfb1SJiri Olsa 		} else {
751e534bfb1SJiri Olsa 			snprintf(buf, buflen, "%s.%06lu",
752e534bfb1SJiri Olsa 				 date, nsec / NSEC_PER_USEC);
753e534bfb1SJiri Olsa 		}
754e534bfb1SJiri Olsa 	}
755e534bfb1SJiri Olsa 
756e534bfb1SJiri Olsa 	return buf;
757e534bfb1SJiri Olsa }
758e534bfb1SJiri Olsa 
perf_sample__fprintf_iregs(struct perf_sample * sample,struct perf_event_attr * attr,const char * arch,FILE * fp)7599add8fe8SMilian Wolff static int perf_sample__fprintf_iregs(struct perf_sample *sample,
76083869019SGerman Gomez 				      struct perf_event_attr *attr, const char *arch, FILE *fp)
7619add8fe8SMilian Wolff {
7629add8fe8SMilian Wolff 	return perf_sample__fprintf_regs(&sample->intr_regs,
76383869019SGerman Gomez 					 attr->sample_regs_intr, arch, fp);
7649add8fe8SMilian Wolff }
7659add8fe8SMilian Wolff 
perf_sample__fprintf_uregs(struct perf_sample * sample,struct perf_event_attr * attr,const char * arch,FILE * fp)7669add8fe8SMilian Wolff static int perf_sample__fprintf_uregs(struct perf_sample *sample,
76783869019SGerman Gomez 				      struct perf_event_attr *attr, const char *arch, FILE *fp)
7689add8fe8SMilian Wolff {
7699add8fe8SMilian Wolff 	return perf_sample__fprintf_regs(&sample->user_regs,
77083869019SGerman Gomez 					 attr->sample_regs_user, arch, fp);
7719add8fe8SMilian Wolff }
7729add8fe8SMilian Wolff 
perf_sample__fprintf_start(struct perf_script * script,struct perf_sample * sample,struct thread * thread,struct evsel * evsel,u32 type,FILE * fp)773e534bfb1SJiri Olsa static int perf_sample__fprintf_start(struct perf_script *script,
774e534bfb1SJiri Olsa 				      struct perf_sample *sample,
7751424dc96SDavid Ahern 				      struct thread *thread,
77632dcd021SJiri Olsa 				      struct evsel *evsel,
77728a0b398SJiri Olsa 				      u32 type, FILE *fp)
778c70c94b4SDavid Ahern {
7791fc632ceSJiri Olsa 	struct perf_event_attr *attr = &evsel->core.attr;
780c70c94b4SDavid Ahern 	unsigned long secs;
781745f43e3SDavid Ahern 	unsigned long long nsecs;
782a1a58707SArnaldo Carvalho de Melo 	int printed = 0;
783e534bfb1SJiri Olsa 	char tstr[128];
784c70c94b4SDavid Ahern 
785e28fb159SAdrian Hunter 	if (PRINT_FIELD(MACHINE_PID) && sample->machine_pid)
786e28fb159SAdrian Hunter 		printed += fprintf(fp, "VM:%5d ", sample->machine_pid);
787e28fb159SAdrian Hunter 
788e28fb159SAdrian Hunter 	/* Print VCPU only for guest events i.e. with machine_pid */
789e28fb159SAdrian Hunter 	if (PRINT_FIELD(VCPU) && sample->machine_pid)
790e28fb159SAdrian Hunter 		printed += fprintf(fp, "VCPU:%03d ", sample->vcpu);
791e28fb159SAdrian Hunter 
792745f43e3SDavid Ahern 	if (PRINT_FIELD(COMM)) {
793fc18380fSAdrian Hunter 		const char *comm = thread ? thread__comm_str(thread) : ":-1";
794fc18380fSAdrian Hunter 
795c70c94b4SDavid Ahern 		if (latency_format)
796fc18380fSAdrian Hunter 			printed += fprintf(fp, "%8.8s ", comm);
797b879833cSArnaldo Carvalho de Melo 		else if (PRINT_FIELD(IP) && evsel__has_callchain(evsel) && symbol_conf.use_callchain)
798fc18380fSAdrian Hunter 			printed += fprintf(fp, "%s ", comm);
799c70c94b4SDavid Ahern 		else
800fc18380fSAdrian Hunter 			printed += fprintf(fp, "%16s ", comm);
801745f43e3SDavid Ahern 	}
802c70c94b4SDavid Ahern 
803745f43e3SDavid Ahern 	if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
804fe8e0434SNamhyung Kim 		printed += fprintf(fp, "%7d/%-7d ", sample->pid, sample->tid);
805745f43e3SDavid Ahern 	else if (PRINT_FIELD(PID))
806fe8e0434SNamhyung Kim 		printed += fprintf(fp, "%7d ", sample->pid);
807745f43e3SDavid Ahern 	else if (PRINT_FIELD(TID))
808fe8e0434SNamhyung Kim 		printed += fprintf(fp, "%7d ", sample->tid);
809745f43e3SDavid Ahern 
810745f43e3SDavid Ahern 	if (PRINT_FIELD(CPU)) {
811745f43e3SDavid Ahern 		if (latency_format)
812a1a58707SArnaldo Carvalho de Melo 			printed += fprintf(fp, "%3d ", sample->cpu);
813745f43e3SDavid Ahern 		else
814a1a58707SArnaldo Carvalho de Melo 			printed += fprintf(fp, "[%03d] ", sample->cpu);
815745f43e3SDavid Ahern 	}
816745f43e3SDavid Ahern 
81728a0b398SJiri Olsa 	if (PRINT_FIELD(MISC)) {
81828a0b398SJiri Olsa 		int ret = 0;
81928a0b398SJiri Olsa 
82028a0b398SJiri Olsa 		#define has(m) \
82128a0b398SJiri Olsa 			(sample->misc & PERF_RECORD_MISC_##m) == PERF_RECORD_MISC_##m
82228a0b398SJiri Olsa 
82328a0b398SJiri Olsa 		if (has(KERNEL))
82428a0b398SJiri Olsa 			ret += fprintf(fp, "K");
82528a0b398SJiri Olsa 		if (has(USER))
82628a0b398SJiri Olsa 			ret += fprintf(fp, "U");
82728a0b398SJiri Olsa 		if (has(HYPERVISOR))
82828a0b398SJiri Olsa 			ret += fprintf(fp, "H");
82928a0b398SJiri Olsa 		if (has(GUEST_KERNEL))
83028a0b398SJiri Olsa 			ret += fprintf(fp, "G");
83128a0b398SJiri Olsa 		if (has(GUEST_USER))
83228a0b398SJiri Olsa 			ret += fprintf(fp, "g");
83328a0b398SJiri Olsa 
83428a0b398SJiri Olsa 		switch (type) {
83528a0b398SJiri Olsa 		case PERF_RECORD_MMAP:
83628a0b398SJiri Olsa 		case PERF_RECORD_MMAP2:
83728a0b398SJiri Olsa 			if (has(MMAP_DATA))
83828a0b398SJiri Olsa 				ret += fprintf(fp, "M");
83928a0b398SJiri Olsa 			break;
84028a0b398SJiri Olsa 		case PERF_RECORD_COMM:
84128a0b398SJiri Olsa 			if (has(COMM_EXEC))
84228a0b398SJiri Olsa 				ret += fprintf(fp, "E");
84328a0b398SJiri Olsa 			break;
84428a0b398SJiri Olsa 		case PERF_RECORD_SWITCH:
84528a0b398SJiri Olsa 		case PERF_RECORD_SWITCH_CPU_WIDE:
846bf30cc18SAlexey Budankov 			if (has(SWITCH_OUT)) {
84728a0b398SJiri Olsa 				ret += fprintf(fp, "S");
848bf30cc18SAlexey Budankov 				if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT)
849bf30cc18SAlexey Budankov 					ret += fprintf(fp, "p");
850bf30cc18SAlexey Budankov 			}
85128a0b398SJiri Olsa 		default:
85228a0b398SJiri Olsa 			break;
85328a0b398SJiri Olsa 		}
85428a0b398SJiri Olsa 
85528a0b398SJiri Olsa 		#undef has
85628a0b398SJiri Olsa 
85728a0b398SJiri Olsa 		ret += fprintf(fp, "%*s", 6 - ret, " ");
85828a0b398SJiri Olsa 		printed += ret;
85928a0b398SJiri Olsa 	}
86028a0b398SJiri Olsa 
861e534bfb1SJiri Olsa 	if (PRINT_FIELD(TOD)) {
862e534bfb1SJiri Olsa 		tod_scnprintf(script, tstr, sizeof(tstr), sample->time);
863e534bfb1SJiri Olsa 		printed += fprintf(fp, "%s ", tstr);
864e534bfb1SJiri Olsa 	}
865e534bfb1SJiri Olsa 
866745f43e3SDavid Ahern 	if (PRINT_FIELD(TIME)) {
86790b10f47SAndi Kleen 		u64 t = sample->time;
86890b10f47SAndi Kleen 		if (reltime) {
86990b10f47SAndi Kleen 			if (!initial_time)
87090b10f47SAndi Kleen 				initial_time = sample->time;
87190b10f47SAndi Kleen 			t = sample->time - initial_time;
87226567ed7SHagen Paul Pfeifer 		} else if (deltatime) {
87326567ed7SHagen Paul Pfeifer 			if (previous_time)
87426567ed7SHagen Paul Pfeifer 				t = sample->time - previous_time;
87526567ed7SHagen Paul Pfeifer 			else {
87626567ed7SHagen Paul Pfeifer 				t = 0;
87726567ed7SHagen Paul Pfeifer 			}
87826567ed7SHagen Paul Pfeifer 			previous_time = sample->time;
87990b10f47SAndi Kleen 		}
88090b10f47SAndi Kleen 		nsecs = t;
881bd48c63eSArnaldo Carvalho de Melo 		secs = nsecs / NSEC_PER_SEC;
882bd48c63eSArnaldo Carvalho de Melo 		nsecs -= secs * NSEC_PER_SEC;
88399620a5dSNamhyung Kim 
88452bab886SAndi Kleen 		if (symbol_conf.nanosecs)
885a1a58707SArnaldo Carvalho de Melo 			printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs);
88699620a5dSNamhyung Kim 		else {
88799620a5dSNamhyung Kim 			char sample_time[32];
88890b10f47SAndi Kleen 			timestamp__scnprintf_usec(t, sample_time, sizeof(sample_time));
889a1a58707SArnaldo Carvalho de Melo 			printed += fprintf(fp, "%12s: ", sample_time);
89099620a5dSNamhyung Kim 		}
891745f43e3SDavid Ahern 	}
892a1a58707SArnaldo Carvalho de Melo 
893a1a58707SArnaldo Carvalho de Melo 	return printed;
894745f43e3SDavid Ahern }
895c70c94b4SDavid Ahern 
896dc323ce8SStephane Eranian static inline char
mispred_str(struct branch_entry * br)897dc323ce8SStephane Eranian mispred_str(struct branch_entry *br)
898dc323ce8SStephane Eranian {
899dc323ce8SStephane Eranian 	if (!(br->flags.mispred  || br->flags.predicted))
900dc323ce8SStephane Eranian 		return '-';
901dc323ce8SStephane Eranian 
902dc323ce8SStephane Eranian 	return br->flags.predicted ? 'P' : 'M';
903dc323ce8SStephane Eranian }
904dc323ce8SStephane Eranian 
print_bstack_flags(FILE * fp,struct branch_entry * br)905b2dac688SJames Clark static int print_bstack_flags(FILE *fp, struct branch_entry *br)
906b2dac688SJames Clark {
9076ade6c64SSandipan Das 	return fprintf(fp, "/%c/%c/%c/%d/%s/%s ",
908b2dac688SJames Clark 		       mispred_str(br),
909b2dac688SJames Clark 		       br->flags.in_tx ? 'X' : '-',
910b2dac688SJames Clark 		       br->flags.abort ? 'A' : '-',
9111f48989cSJames Clark 		       br->flags.cycles,
9126ade6c64SSandipan Das 		       get_branch_type(br),
9136ade6c64SSandipan Das 		       br->flags.spec ? branch_spec_desc(br->flags.spec) : "-");
914b2dac688SJames Clark }
915b2dac688SJames Clark 
perf_sample__fprintf_brstack(struct perf_sample * sample,struct thread * thread,struct perf_event_attr * attr,FILE * fp)916a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_brstack(struct perf_sample *sample,
91755b9b508SMark Santaniello 					struct thread *thread,
918a1a58707SArnaldo Carvalho de Melo 					struct perf_event_attr *attr, FILE *fp)
919dc323ce8SStephane Eranian {
920dc323ce8SStephane Eranian 	struct branch_stack *br = sample->branch_stack;
92142bbabedSKan Liang 	struct branch_entry *entries = perf_sample__branch_entries(sample);
92255b9b508SMark Santaniello 	u64 i, from, to;
923a1a58707SArnaldo Carvalho de Melo 	int printed = 0;
924dc323ce8SStephane Eranian 
925dc323ce8SStephane Eranian 	if (!(br && br->nr))
926a1a58707SArnaldo Carvalho de Melo 		return 0;
927dc323ce8SStephane Eranian 
928dc323ce8SStephane Eranian 	for (i = 0; i < br->nr; i++) {
92942bbabedSKan Liang 		from = entries[i].from;
93042bbabedSKan Liang 		to   = entries[i].to;
93155b9b508SMark Santaniello 
9320dd5041cSIan Rogers 		printed += fprintf(fp, " 0x%"PRIx64, from);
93355b9b508SMark Santaniello 		if (PRINT_FIELD(DSO)) {
9340dd5041cSIan Rogers 			struct addr_location alf, alt;
9350dd5041cSIan Rogers 
9360dd5041cSIan Rogers 			addr_location__init(&alf);
9370dd5041cSIan Rogers 			addr_location__init(&alt);
938692d0e63SAdrian Hunter 			thread__find_map_fb(thread, sample->cpumode, from, &alf);
939692d0e63SAdrian Hunter 			thread__find_map_fb(thread, sample->cpumode, to, &alt);
94055b9b508SMark Santaniello 
941af9eb56bSChangbin Du 			printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);
942a1a58707SArnaldo Carvalho de Melo 			printed += fprintf(fp, "/0x%"PRIx64, to);
943af9eb56bSChangbin Du 			printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);
9440dd5041cSIan Rogers 			addr_location__exit(&alt);
9450dd5041cSIan Rogers 			addr_location__exit(&alf);
9460dd5041cSIan Rogers 		} else
9470dd5041cSIan Rogers 			printed += fprintf(fp, "/0x%"PRIx64, to);
94855b9b508SMark Santaniello 
949b2dac688SJames Clark 		printed += print_bstack_flags(fp, entries + i);
950dc323ce8SStephane Eranian 	}
951a1a58707SArnaldo Carvalho de Melo 
952a1a58707SArnaldo Carvalho de Melo 	return printed;
953dc323ce8SStephane Eranian }
954dc323ce8SStephane Eranian 
perf_sample__fprintf_brstacksym(struct perf_sample * sample,struct thread * thread,struct perf_event_attr * attr,FILE * fp)955a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
95655b9b508SMark Santaniello 					   struct thread *thread,
957a1a58707SArnaldo Carvalho de Melo 					   struct perf_event_attr *attr, FILE *fp)
958dc323ce8SStephane Eranian {
959dc323ce8SStephane Eranian 	struct branch_stack *br = sample->branch_stack;
96042bbabedSKan Liang 	struct branch_entry *entries = perf_sample__branch_entries(sample);
961dc323ce8SStephane Eranian 	u64 i, from, to;
962a1a58707SArnaldo Carvalho de Melo 	int printed = 0;
963dc323ce8SStephane Eranian 
964dc323ce8SStephane Eranian 	if (!(br && br->nr))
965a1a58707SArnaldo Carvalho de Melo 		return 0;
966dc323ce8SStephane Eranian 
967dc323ce8SStephane Eranian 	for (i = 0; i < br->nr; i++) {
9680dd5041cSIan Rogers 		struct addr_location alf, alt;
969dc323ce8SStephane Eranian 
9700dd5041cSIan Rogers 		addr_location__init(&alf);
9710dd5041cSIan Rogers 		addr_location__init(&alt);
97242bbabedSKan Liang 		from = entries[i].from;
97342bbabedSKan Liang 		to   = entries[i].to;
974dc323ce8SStephane Eranian 
975692d0e63SAdrian Hunter 		thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
976692d0e63SAdrian Hunter 		thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
977dc323ce8SStephane Eranian 
978a1a58707SArnaldo Carvalho de Melo 		printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
979af9eb56bSChangbin Du 		if (PRINT_FIELD(DSO))
980af9eb56bSChangbin Du 			printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);
981a1a58707SArnaldo Carvalho de Melo 		printed += fprintf(fp, "%c", '/');
982a1a58707SArnaldo Carvalho de Melo 		printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp);
983af9eb56bSChangbin Du 		if (PRINT_FIELD(DSO))
984af9eb56bSChangbin Du 			printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);
985b2dac688SJames Clark 		printed += print_bstack_flags(fp, entries + i);
9860dd5041cSIan Rogers 		addr_location__exit(&alt);
9870dd5041cSIan Rogers 		addr_location__exit(&alf);
988dc323ce8SStephane Eranian 	}
989a1a58707SArnaldo Carvalho de Melo 
990a1a58707SArnaldo Carvalho de Melo 	return printed;
991dc323ce8SStephane Eranian }
992dc323ce8SStephane Eranian 
perf_sample__fprintf_brstackoff(struct perf_sample * sample,struct thread * thread,struct perf_event_attr * attr,FILE * fp)993a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
994106dacd8SMark Santaniello 					   struct thread *thread,
995a1a58707SArnaldo Carvalho de Melo 					   struct perf_event_attr *attr, FILE *fp)
996106dacd8SMark Santaniello {
997106dacd8SMark Santaniello 	struct branch_stack *br = sample->branch_stack;
99842bbabedSKan Liang 	struct branch_entry *entries = perf_sample__branch_entries(sample);
999106dacd8SMark Santaniello 	u64 i, from, to;
1000a1a58707SArnaldo Carvalho de Melo 	int printed = 0;
1001106dacd8SMark Santaniello 
1002106dacd8SMark Santaniello 	if (!(br && br->nr))
1003a1a58707SArnaldo Carvalho de Melo 		return 0;
1004106dacd8SMark Santaniello 
1005106dacd8SMark Santaniello 	for (i = 0; i < br->nr; i++) {
10060dd5041cSIan Rogers 		struct addr_location alf, alt;
1007106dacd8SMark Santaniello 
10080dd5041cSIan Rogers 		addr_location__init(&alf);
10090dd5041cSIan Rogers 		addr_location__init(&alt);
101042bbabedSKan Liang 		from = entries[i].from;
101142bbabedSKan Liang 		to   = entries[i].to;
1012106dacd8SMark Santaniello 
1013692d0e63SAdrian Hunter 		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
101463df0e4bSIan Rogers 		    !map__dso(alf.map)->adjust_symbols)
10150e6aa013SIan Rogers 			from = map__dso_map_ip(alf.map, from);
1016106dacd8SMark Santaniello 
1017692d0e63SAdrian Hunter 		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
101863df0e4bSIan Rogers 		    !map__dso(alt.map)->adjust_symbols)
10190e6aa013SIan Rogers 			to = map__dso_map_ip(alt.map, to);
1020106dacd8SMark Santaniello 
1021a1a58707SArnaldo Carvalho de Melo 		printed += fprintf(fp, " 0x%"PRIx64, from);
1022af9eb56bSChangbin Du 		if (PRINT_FIELD(DSO))
1023af9eb56bSChangbin Du 			printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);
1024a1a58707SArnaldo Carvalho de Melo 		printed += fprintf(fp, "/0x%"PRIx64, to);
1025af9eb56bSChangbin Du 		if (PRINT_FIELD(DSO))
1026af9eb56bSChangbin Du 			printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);
1027b2dac688SJames Clark 		printed += print_bstack_flags(fp, entries + i);
10280dd5041cSIan Rogers 		addr_location__exit(&alt);
10290dd5041cSIan Rogers 		addr_location__exit(&alf);
1030106dacd8SMark Santaniello 	}
1031a1a58707SArnaldo Carvalho de Melo 
1032a1a58707SArnaldo Carvalho de Melo 	return printed;
1033106dacd8SMark Santaniello }
103448d02a1dSAndi Kleen #define MAXBB 16384UL
103548d02a1dSAndi Kleen 
grab_bb(u8 * buffer,u64 start,u64 end,struct machine * machine,struct thread * thread,bool * is64bit,u8 * cpumode,bool last)103648d02a1dSAndi Kleen static int grab_bb(u8 *buffer, u64 start, u64 end,
103748d02a1dSAndi Kleen 		    struct machine *machine, struct thread *thread,
103848d02a1dSAndi Kleen 		    bool *is64bit, u8 *cpumode, bool last)
103948d02a1dSAndi Kleen {
104048d02a1dSAndi Kleen 	long offset, len;
104148d02a1dSAndi Kleen 	struct addr_location al;
104248d02a1dSAndi Kleen 	bool kernel;
104363df0e4bSIan Rogers 	struct dso *dso;
10440dd5041cSIan Rogers 	int ret = 0;
104548d02a1dSAndi Kleen 
104648d02a1dSAndi Kleen 	if (!start || !end)
104748d02a1dSAndi Kleen 		return 0;
104848d02a1dSAndi Kleen 
104948d02a1dSAndi Kleen 	kernel = machine__kernel_ip(machine, start);
105048d02a1dSAndi Kleen 	if (kernel)
105148d02a1dSAndi Kleen 		*cpumode = PERF_RECORD_MISC_KERNEL;
105248d02a1dSAndi Kleen 	else
105348d02a1dSAndi Kleen 		*cpumode = PERF_RECORD_MISC_USER;
105448d02a1dSAndi Kleen 
105548d02a1dSAndi Kleen 	/*
105648d02a1dSAndi Kleen 	 * Block overlaps between kernel and user.
105748d02a1dSAndi Kleen 	 * This can happen due to ring filtering
105848d02a1dSAndi Kleen 	 * On Intel CPUs the entry into the kernel is filtered,
105948d02a1dSAndi Kleen 	 * but the exit is not. Let the caller patch it up.
106048d02a1dSAndi Kleen 	 */
106148d02a1dSAndi Kleen 	if (kernel != machine__kernel_ip(machine, end)) {
10625ce2c5b4SArnaldo Carvalho de Melo 		pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end);
106348d02a1dSAndi Kleen 		return -ENXIO;
106448d02a1dSAndi Kleen 	}
106548d02a1dSAndi Kleen 
106648d02a1dSAndi Kleen 	if (end - start > MAXBB - MAXINSN) {
106748d02a1dSAndi Kleen 		if (last)
10685ce2c5b4SArnaldo Carvalho de Melo 			pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end);
106948d02a1dSAndi Kleen 		else
10705ce2c5b4SArnaldo Carvalho de Melo 			pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start);
107148d02a1dSAndi Kleen 		return 0;
107248d02a1dSAndi Kleen 	}
107348d02a1dSAndi Kleen 
10740dd5041cSIan Rogers 	addr_location__init(&al);
10753ad1be6fSArnaldo Carvalho de Melo 	if (!thread__find_map(thread, *cpumode, start, &al) || (dso = map__dso(al.map)) == NULL) {
10765ce2c5b4SArnaldo Carvalho de Melo 		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
10770dd5041cSIan Rogers 		goto out;
107848d02a1dSAndi Kleen 	}
107963df0e4bSIan Rogers 	if (dso->data.status == DSO_DATA_STATUS_ERROR) {
10805ce2c5b4SArnaldo Carvalho de Melo 		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
10810dd5041cSIan Rogers 		goto out;
108248d02a1dSAndi Kleen 	}
108348d02a1dSAndi Kleen 
108448d02a1dSAndi Kleen 	/* Load maps to ensure dso->is_64_bit has been updated */
108548d02a1dSAndi Kleen 	map__load(al.map);
108648d02a1dSAndi Kleen 
108778a1f7cdSIan Rogers 	offset = map__map_ip(al.map, start);
108863df0e4bSIan Rogers 	len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer,
108948d02a1dSAndi Kleen 				    end - start + MAXINSN);
109048d02a1dSAndi Kleen 
109163df0e4bSIan Rogers 	*is64bit = dso->is_64_bit;
109248d02a1dSAndi Kleen 	if (len <= 0)
10935ce2c5b4SArnaldo Carvalho de Melo 		pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
109448d02a1dSAndi Kleen 			start, end);
10950dd5041cSIan Rogers 	ret = len;
10960dd5041cSIan Rogers out:
10970dd5041cSIan Rogers 	addr_location__exit(&al);
10980dd5041cSIan Rogers 	return ret;
109948d02a1dSAndi Kleen }
110048d02a1dSAndi Kleen 
map__fprintf_srccode(struct map * map,u64 addr,FILE * fp,struct srccode_state * state)1101540a63eaSArnaldo Carvalho de Melo static int map__fprintf_srccode(struct map *map, u64 addr, FILE *fp, struct srccode_state *state)
1102540a63eaSArnaldo Carvalho de Melo {
1103540a63eaSArnaldo Carvalho de Melo 	char *srcfile;
1104540a63eaSArnaldo Carvalho de Melo 	int ret = 0;
1105540a63eaSArnaldo Carvalho de Melo 	unsigned line;
1106540a63eaSArnaldo Carvalho de Melo 	int len;
1107540a63eaSArnaldo Carvalho de Melo 	char *srccode;
11083ad1be6fSArnaldo Carvalho de Melo 	struct dso *dso;
1109540a63eaSArnaldo Carvalho de Melo 
11103ad1be6fSArnaldo Carvalho de Melo 	if (!map || (dso = map__dso(map)) == NULL)
1111540a63eaSArnaldo Carvalho de Melo 		return 0;
111263df0e4bSIan Rogers 	srcfile = get_srcline_split(dso,
1113540a63eaSArnaldo Carvalho de Melo 				    map__rip_2objdump(map, addr),
1114540a63eaSArnaldo Carvalho de Melo 				    &line);
1115540a63eaSArnaldo Carvalho de Melo 	if (!srcfile)
1116540a63eaSArnaldo Carvalho de Melo 		return 0;
1117540a63eaSArnaldo Carvalho de Melo 
1118540a63eaSArnaldo Carvalho de Melo 	/* Avoid redundant printing */
1119540a63eaSArnaldo Carvalho de Melo 	if (state &&
1120540a63eaSArnaldo Carvalho de Melo 	    state->srcfile &&
1121540a63eaSArnaldo Carvalho de Melo 	    !strcmp(state->srcfile, srcfile) &&
1122540a63eaSArnaldo Carvalho de Melo 	    state->line == line) {
1123540a63eaSArnaldo Carvalho de Melo 		free(srcfile);
1124540a63eaSArnaldo Carvalho de Melo 		return 0;
1125540a63eaSArnaldo Carvalho de Melo 	}
1126540a63eaSArnaldo Carvalho de Melo 
1127540a63eaSArnaldo Carvalho de Melo 	srccode = find_sourceline(srcfile, line, &len);
1128540a63eaSArnaldo Carvalho de Melo 	if (!srccode)
1129540a63eaSArnaldo Carvalho de Melo 		goto out_free_line;
1130540a63eaSArnaldo Carvalho de Melo 
1131540a63eaSArnaldo Carvalho de Melo 	ret = fprintf(fp, "|%-8d %.*s", line, len, srccode);
1132540a63eaSArnaldo Carvalho de Melo 
1133540a63eaSArnaldo Carvalho de Melo 	if (state) {
1134540a63eaSArnaldo Carvalho de Melo 		state->srcfile = srcfile;
1135540a63eaSArnaldo Carvalho de Melo 		state->line = line;
1136540a63eaSArnaldo Carvalho de Melo 	}
1137540a63eaSArnaldo Carvalho de Melo 	return ret;
1138540a63eaSArnaldo Carvalho de Melo 
1139540a63eaSArnaldo Carvalho de Melo out_free_line:
1140540a63eaSArnaldo Carvalho de Melo 	free(srcfile);
1141540a63eaSArnaldo Carvalho de Melo 	return ret;
1142540a63eaSArnaldo Carvalho de Melo }
1143540a63eaSArnaldo Carvalho de Melo 
print_srccode(struct thread * thread,u8 cpumode,uint64_t addr)1144dd2e18e9SAndi Kleen static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr)
1145dd2e18e9SAndi Kleen {
1146dd2e18e9SAndi Kleen 	struct addr_location al;
1147dd2e18e9SAndi Kleen 	int ret = 0;
1148dd2e18e9SAndi Kleen 
11490dd5041cSIan Rogers 	addr_location__init(&al);
1150dd2e18e9SAndi Kleen 	thread__find_map(thread, cpumode, addr, &al);
1151dd2e18e9SAndi Kleen 	if (!al.map)
11520dd5041cSIan Rogers 		goto out;
1153dd2e18e9SAndi Kleen 	ret = map__fprintf_srccode(al.map, al.addr, stdout,
1154ee84a303SIan Rogers 				   thread__srccode_state(thread));
1155dd2e18e9SAndi Kleen 	if (ret)
1156dd2e18e9SAndi Kleen 		ret += printf("\n");
11570dd5041cSIan Rogers out:
11580dd5041cSIan Rogers 	addr_location__exit(&al);
1159dd2e18e9SAndi Kleen 	return ret;
1160dd2e18e9SAndi Kleen }
1161dd2e18e9SAndi Kleen 
ip__fprintf_jump(uint64_t ip,struct branch_entry * en,struct perf_insn * x,u8 * inbuf,int len,int insn,FILE * fp,int * total_cycles,struct perf_event_attr * attr)1162a1a58707SArnaldo Carvalho de Melo static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
116348d02a1dSAndi Kleen 			    struct perf_insn *x, u8 *inbuf, int len,
11646f680c6aSKan Liang 			    int insn, FILE *fp, int *total_cycles,
11656f680c6aSKan Liang 			    struct perf_event_attr *attr)
116648d02a1dSAndi Kleen {
11676f680c6aSKan Liang 	int ilen = 0;
11686f680c6aSKan Liang 	int printed = fprintf(fp, "\t%016" PRIx64 "\t%-30s\t", ip,
11696f680c6aSKan Liang 			      dump_insn(x, ip, inbuf, len, &ilen));
11706f680c6aSKan Liang 
11716f680c6aSKan Liang 	if (PRINT_FIELD(BRSTACKINSNLEN))
11726f680c6aSKan Liang 		printed += fprintf(fp, "ilen: %d\t", ilen);
11736f680c6aSKan Liang 
11746f680c6aSKan Liang 	printed += fprintf(fp, "#%s%s%s%s",
117548d02a1dSAndi Kleen 			      en->flags.predicted ? " PRED" : "",
117648d02a1dSAndi Kleen 			      en->flags.mispred ? " MISPRED" : "",
117748d02a1dSAndi Kleen 			      en->flags.in_tx ? " INTX" : "",
117848d02a1dSAndi Kleen 			      en->flags.abort ? " ABORT" : "");
117948d02a1dSAndi Kleen 	if (en->flags.cycles) {
1180fe57120eSAndi Kleen 		*total_cycles += en->flags.cycles;
1181fe57120eSAndi Kleen 		printed += fprintf(fp, " %d cycles [%d]", en->flags.cycles, *total_cycles);
118248d02a1dSAndi Kleen 		if (insn)
1183a1a58707SArnaldo Carvalho de Melo 			printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
118448d02a1dSAndi Kleen 	}
1185a1a58707SArnaldo Carvalho de Melo 	return printed + fprintf(fp, "\n");
118648d02a1dSAndi Kleen }
118748d02a1dSAndi Kleen 
ip__fprintf_sym(uint64_t addr,struct thread * thread,u8 cpumode,int cpu,struct symbol ** lastsym,struct perf_event_attr * attr,FILE * fp)1188a1a58707SArnaldo Carvalho de Melo static int ip__fprintf_sym(uint64_t addr, struct thread *thread,
1189a1a58707SArnaldo Carvalho de Melo 			   u8 cpumode, int cpu, struct symbol **lastsym,
1190a1a58707SArnaldo Carvalho de Melo 			   struct perf_event_attr *attr, FILE *fp)
119148d02a1dSAndi Kleen {
119248d02a1dSAndi Kleen 	struct addr_location al;
11930dd5041cSIan Rogers 	int off, printed = 0, ret = 0;
119448d02a1dSAndi Kleen 
11950dd5041cSIan Rogers 	addr_location__init(&al);
1196404eb5a4SArnaldo Carvalho de Melo 	thread__find_map(thread, cpumode, addr, &al);
1197404eb5a4SArnaldo Carvalho de Melo 
119848d02a1dSAndi Kleen 	if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
11990dd5041cSIan Rogers 		goto out;
120048d02a1dSAndi Kleen 
120148d02a1dSAndi Kleen 	al.cpu = cpu;
120248d02a1dSAndi Kleen 	al.sym = NULL;
120348d02a1dSAndi Kleen 	if (al.map)
120448d02a1dSAndi Kleen 		al.sym = map__find_symbol(al.map, al.addr);
120548d02a1dSAndi Kleen 
120648d02a1dSAndi Kleen 	if (!al.sym)
12070dd5041cSIan Rogers 		goto out;
120848d02a1dSAndi Kleen 
120948d02a1dSAndi Kleen 	if (al.addr < al.sym->end)
121048d02a1dSAndi Kleen 		off = al.addr - al.sym->start;
121148d02a1dSAndi Kleen 	else
1212e5116f46SIan Rogers 		off = al.addr - map__start(al.map) - al.sym->start;
1213a1a58707SArnaldo Carvalho de Melo 	printed += fprintf(fp, "\t%s", al.sym->name);
121448d02a1dSAndi Kleen 	if (off)
1215a1a58707SArnaldo Carvalho de Melo 		printed += fprintf(fp, "%+d", off);
1216a1a58707SArnaldo Carvalho de Melo 	printed += fprintf(fp, ":");
121748d02a1dSAndi Kleen 	if (PRINT_FIELD(SRCLINE))
1218a1a58707SArnaldo Carvalho de Melo 		printed += map__fprintf_srcline(al.map, al.addr, "\t", fp);
1219a1a58707SArnaldo Carvalho de Melo 	printed += fprintf(fp, "\n");
122048d02a1dSAndi Kleen 	*lastsym = al.sym;
1221a1a58707SArnaldo Carvalho de Melo 
12220dd5041cSIan Rogers 	ret = printed;
12230dd5041cSIan Rogers out:
12240dd5041cSIan Rogers 	addr_location__exit(&al);
12250dd5041cSIan Rogers 	return ret;
122648d02a1dSAndi Kleen }
122748d02a1dSAndi Kleen 
perf_sample__fprintf_brstackinsn(struct perf_sample * sample,struct thread * thread,struct perf_event_attr * attr,struct machine * machine,FILE * fp)1228a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
122948d02a1dSAndi Kleen 					    struct thread *thread,
123048d02a1dSAndi Kleen 					    struct perf_event_attr *attr,
1231a1a58707SArnaldo Carvalho de Melo 					    struct machine *machine, FILE *fp)
123248d02a1dSAndi Kleen {
123348d02a1dSAndi Kleen 	struct branch_stack *br = sample->branch_stack;
123442bbabedSKan Liang 	struct branch_entry *entries = perf_sample__branch_entries(sample);
123548d02a1dSAndi Kleen 	u64 start, end;
1236a1a58707SArnaldo Carvalho de Melo 	int i, insn, len, nr, ilen, printed = 0;
123748d02a1dSAndi Kleen 	struct perf_insn x;
123848d02a1dSAndi Kleen 	u8 buffer[MAXBB];
123948d02a1dSAndi Kleen 	unsigned off;
124048d02a1dSAndi Kleen 	struct symbol *lastsym = NULL;
1241fe57120eSAndi Kleen 	int total_cycles = 0;
124248d02a1dSAndi Kleen 
124348d02a1dSAndi Kleen 	if (!(br && br->nr))
1244a1a58707SArnaldo Carvalho de Melo 		return 0;
124548d02a1dSAndi Kleen 	nr = br->nr;
124648d02a1dSAndi Kleen 	if (max_blocks && nr > max_blocks + 1)
124748d02a1dSAndi Kleen 		nr = max_blocks + 1;
124848d02a1dSAndi Kleen 
124948d02a1dSAndi Kleen 	x.thread = thread;
125048d02a1dSAndi Kleen 	x.cpu = sample->cpu;
125148d02a1dSAndi Kleen 
1252a1a58707SArnaldo Carvalho de Melo 	printed += fprintf(fp, "%c", '\n');
125348d02a1dSAndi Kleen 
125448d02a1dSAndi Kleen 	/* Handle first from jump, of which we don't know the entry. */
125542bbabedSKan Liang 	len = grab_bb(buffer, entries[nr-1].from,
125642bbabedSKan Liang 			entries[nr-1].from,
125748d02a1dSAndi Kleen 			machine, thread, &x.is64bit, &x.cpumode, false);
125848d02a1dSAndi Kleen 	if (len > 0) {
125942bbabedSKan Liang 		printed += ip__fprintf_sym(entries[nr - 1].from, thread,
1260a1a58707SArnaldo Carvalho de Melo 					   x.cpumode, x.cpu, &lastsym, attr, fp);
126142bbabedSKan Liang 		printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1],
12626f680c6aSKan Liang 					    &x, buffer, len, 0, fp, &total_cycles,
12636f680c6aSKan Liang 					    attr);
1264dd2e18e9SAndi Kleen 		if (PRINT_FIELD(SRCCODE))
126542bbabedSKan Liang 			printed += print_srccode(thread, x.cpumode, entries[nr - 1].from);
126648d02a1dSAndi Kleen 	}
126748d02a1dSAndi Kleen 
126848d02a1dSAndi Kleen 	/* Print all blocks */
126948d02a1dSAndi Kleen 	for (i = nr - 2; i >= 0; i--) {
127042bbabedSKan Liang 		if (entries[i].from || entries[i].to)
127148d02a1dSAndi Kleen 			pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i,
127242bbabedSKan Liang 				 entries[i].from,
127342bbabedSKan Liang 				 entries[i].to);
127442bbabedSKan Liang 		start = entries[i + 1].to;
127542bbabedSKan Liang 		end   = entries[i].from;
127648d02a1dSAndi Kleen 
127748d02a1dSAndi Kleen 		len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
127848d02a1dSAndi Kleen 		/* Patch up missing kernel transfers due to ring filters */
127948d02a1dSAndi Kleen 		if (len == -ENXIO && i > 0) {
128042bbabedSKan Liang 			end = entries[--i].from;
128148d02a1dSAndi Kleen 			pr_debug("\tpatching up to %" PRIx64 "-%" PRIx64 "\n", start, end);
128248d02a1dSAndi Kleen 			len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
128348d02a1dSAndi Kleen 		}
128448d02a1dSAndi Kleen 		if (len <= 0)
128548d02a1dSAndi Kleen 			continue;
128648d02a1dSAndi Kleen 
128748d02a1dSAndi Kleen 		insn = 0;
1288e98df280SAndi Kleen 		for (off = 0; off < (unsigned)len; off += ilen) {
128948d02a1dSAndi Kleen 			uint64_t ip = start + off;
129048d02a1dSAndi Kleen 
1291a1a58707SArnaldo Carvalho de Melo 			printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
129248d02a1dSAndi Kleen 			if (ip == end) {
129342bbabedSKan Liang 				printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp,
12946f680c6aSKan Liang 							    &total_cycles, attr);
1295dd2e18e9SAndi Kleen 				if (PRINT_FIELD(SRCCODE))
1296dd2e18e9SAndi Kleen 					printed += print_srccode(thread, x.cpumode, ip);
129748d02a1dSAndi Kleen 				break;
129848d02a1dSAndi Kleen 			} else {
1299e98df280SAndi Kleen 				ilen = 0;
13006f680c6aSKan Liang 				printed += fprintf(fp, "\t%016" PRIx64 "\t%s", ip,
130148d02a1dSAndi Kleen 						   dump_insn(&x, ip, buffer + off, len - off, &ilen));
13026f680c6aSKan Liang 				if (PRINT_FIELD(BRSTACKINSNLEN))
13036f680c6aSKan Liang 					printed += fprintf(fp, "\tilen: %d", ilen);
13046f680c6aSKan Liang 				printed += fprintf(fp, "\n");
130548d02a1dSAndi Kleen 				if (ilen == 0)
130648d02a1dSAndi Kleen 					break;
1307dd2e18e9SAndi Kleen 				if (PRINT_FIELD(SRCCODE))
1308dd2e18e9SAndi Kleen 					print_srccode(thread, x.cpumode, ip);
130948d02a1dSAndi Kleen 				insn++;
131048d02a1dSAndi Kleen 			}
131148d02a1dSAndi Kleen 		}
13125172672dSAdrian Hunter 		if (off != end - start)
1313e98df280SAndi Kleen 			printed += fprintf(fp, "\tmismatch of LBR data and executable\n");
131448d02a1dSAndi Kleen 	}
131548d02a1dSAndi Kleen 
131648d02a1dSAndi Kleen 	/*
131748d02a1dSAndi Kleen 	 * Hit the branch? In this case we are already done, and the target
131848d02a1dSAndi Kleen 	 * has not been executed yet.
131948d02a1dSAndi Kleen 	 */
132042bbabedSKan Liang 	if (entries[0].from == sample->ip)
1321a1a58707SArnaldo Carvalho de Melo 		goto out;
132242bbabedSKan Liang 	if (entries[0].flags.abort)
1323a1a58707SArnaldo Carvalho de Melo 		goto out;
132448d02a1dSAndi Kleen 
132548d02a1dSAndi Kleen 	/*
132648d02a1dSAndi Kleen 	 * Print final block up to sample
132761f61159SAndi Kleen 	 *
132861f61159SAndi Kleen 	 * Due to pipeline delays the LBRs might be missing a branch
132961f61159SAndi Kleen 	 * or two, which can result in very large or negative blocks
133061f61159SAndi Kleen 	 * between final branch and sample. When this happens just
133161f61159SAndi Kleen 	 * continue walking after the last TO until we hit a branch.
133248d02a1dSAndi Kleen 	 */
133342bbabedSKan Liang 	start = entries[0].to;
133448d02a1dSAndi Kleen 	end = sample->ip;
133561f61159SAndi Kleen 	if (end < start) {
133661f61159SAndi Kleen 		/* Missing jump. Scan 128 bytes for the next branch */
133761f61159SAndi Kleen 		end = start + 128;
133861f61159SAndi Kleen 	}
133948d02a1dSAndi Kleen 	len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
1340a1a58707SArnaldo Carvalho de Melo 	printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
134148d02a1dSAndi Kleen 	if (len <= 0) {
134248d02a1dSAndi Kleen 		/* Print at least last IP if basic block did not work */
134348d02a1dSAndi Kleen 		len = grab_bb(buffer, sample->ip, sample->ip,
134448d02a1dSAndi Kleen 			      machine, thread, &x.is64bit, &x.cpumode, false);
134548d02a1dSAndi Kleen 		if (len <= 0)
1346a1a58707SArnaldo Carvalho de Melo 			goto out;
13476f680c6aSKan Liang 		ilen = 0;
13486f680c6aSKan Liang 		printed += fprintf(fp, "\t%016" PRIx64 "\t%s", sample->ip,
13496f680c6aSKan Liang 			dump_insn(&x, sample->ip, buffer, len, &ilen));
13506f680c6aSKan Liang 		if (PRINT_FIELD(BRSTACKINSNLEN))
13516f680c6aSKan Liang 			printed += fprintf(fp, "\tilen: %d", ilen);
13526f680c6aSKan Liang 		printed += fprintf(fp, "\n");
1353dd2e18e9SAndi Kleen 		if (PRINT_FIELD(SRCCODE))
1354dd2e18e9SAndi Kleen 			print_srccode(thread, x.cpumode, sample->ip);
1355a1a58707SArnaldo Carvalho de Melo 		goto out;
135648d02a1dSAndi Kleen 	}
135748d02a1dSAndi Kleen 	for (off = 0; off <= end - start; off += ilen) {
1358e98df280SAndi Kleen 		ilen = 0;
13596f680c6aSKan Liang 		printed += fprintf(fp, "\t%016" PRIx64 "\t%s", start + off,
136048d02a1dSAndi Kleen 				   dump_insn(&x, start + off, buffer + off, len - off, &ilen));
13616f680c6aSKan Liang 		if (PRINT_FIELD(BRSTACKINSNLEN))
13626f680c6aSKan Liang 			printed += fprintf(fp, "\tilen: %d", ilen);
13636f680c6aSKan Liang 		printed += fprintf(fp, "\n");
136448d02a1dSAndi Kleen 		if (ilen == 0)
136548d02a1dSAndi Kleen 			break;
136661f61159SAndi Kleen 		if (arch_is_branch(buffer + off, len - off, x.is64bit) && start + off != sample->ip) {
136761f61159SAndi Kleen 			/*
136861f61159SAndi Kleen 			 * Hit a missing branch. Just stop.
136961f61159SAndi Kleen 			 */
137061f61159SAndi Kleen 			printed += fprintf(fp, "\t... not reaching sample ...\n");
137161f61159SAndi Kleen 			break;
137261f61159SAndi Kleen 		}
1373dd2e18e9SAndi Kleen 		if (PRINT_FIELD(SRCCODE))
1374dd2e18e9SAndi Kleen 			print_srccode(thread, x.cpumode, start + off);
137548d02a1dSAndi Kleen 	}
1376a1a58707SArnaldo Carvalho de Melo out:
1377a1a58707SArnaldo Carvalho de Melo 	return printed;
137848d02a1dSAndi Kleen }
1379dc323ce8SStephane Eranian 
perf_sample__fprintf_addr(struct perf_sample * sample,struct thread * thread,struct perf_event_attr * attr,FILE * fp)1380a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_addr(struct perf_sample *sample,
13817cec0922SDavid Ahern 				     struct thread *thread,
1382a1a58707SArnaldo Carvalho de Melo 				     struct perf_event_attr *attr, FILE *fp)
13837cec0922SDavid Ahern {
13847cec0922SDavid Ahern 	struct addr_location al;
1385a1a58707SArnaldo Carvalho de Melo 	int printed = fprintf(fp, "%16" PRIx64, sample->addr);
13867cec0922SDavid Ahern 
13870dd5041cSIan Rogers 	addr_location__init(&al);
13887cec0922SDavid Ahern 	if (!sample_addr_correlates_sym(attr))
1389a1a58707SArnaldo Carvalho de Melo 		goto out;
13907cec0922SDavid Ahern 
1391c2740a87SArnaldo Carvalho de Melo 	thread__resolve(thread, &al, sample);
13927cec0922SDavid Ahern 
13937cec0922SDavid Ahern 	if (PRINT_FIELD(SYM)) {
1394a1a58707SArnaldo Carvalho de Melo 		printed += fprintf(fp, " ");
1395a978f2abSAkihiro Nagai 		if (PRINT_FIELD(SYMOFFSET))
1396a1a58707SArnaldo Carvalho de Melo 			printed += symbol__fprintf_symname_offs(al.sym, &al, fp);
1397a978f2abSAkihiro Nagai 		else
1398a1a58707SArnaldo Carvalho de Melo 			printed += symbol__fprintf_symname(al.sym, fp);
13997cec0922SDavid Ahern 	}
14007cec0922SDavid Ahern 
1401af9eb56bSChangbin Du 	if (PRINT_FIELD(DSO))
1402af9eb56bSChangbin Du 		printed += map__fprintf_dsoname_dsoff(al.map, PRINT_FIELD(DSOFF), al.addr, fp);
1403a1a58707SArnaldo Carvalho de Melo out:
14040dd5041cSIan Rogers 	addr_location__exit(&al);
1405a1a58707SArnaldo Carvalho de Melo 	return printed;
14067cec0922SDavid Ahern }
14077cec0922SDavid Ahern 
resolve_branch_sym(struct perf_sample * sample,struct evsel * evsel,struct thread * thread,struct addr_location * al,struct addr_location * addr_al,u64 * ip)140899f753f0SAndi Kleen static const char *resolve_branch_sym(struct perf_sample *sample,
140932dcd021SJiri Olsa 				      struct evsel *evsel,
141099f753f0SAndi Kleen 				      struct thread *thread,
141199f753f0SAndi Kleen 				      struct addr_location *al,
1412b743b86cSAdrian Hunter 				      struct addr_location *addr_al,
141399f753f0SAndi Kleen 				      u64 *ip)
141499f753f0SAndi Kleen {
14151fc632ceSJiri Olsa 	struct perf_event_attr *attr = &evsel->core.attr;
141699f753f0SAndi Kleen 	const char *name = NULL;
141799f753f0SAndi Kleen 
141899f753f0SAndi Kleen 	if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) {
141999f753f0SAndi Kleen 		if (sample_addr_correlates_sym(attr)) {
1420b743b86cSAdrian Hunter 			if (!addr_al->thread)
1421b743b86cSAdrian Hunter 				thread__resolve(thread, addr_al, sample);
1422b743b86cSAdrian Hunter 			if (addr_al->sym)
1423b743b86cSAdrian Hunter 				name = addr_al->sym->name;
142499f753f0SAndi Kleen 			else
142599f753f0SAndi Kleen 				*ip = sample->addr;
142699f753f0SAndi Kleen 		} else {
142799f753f0SAndi Kleen 			*ip = sample->addr;
142899f753f0SAndi Kleen 		}
142999f753f0SAndi Kleen 	} else if (sample->flags & (PERF_IP_FLAG_RETURN | PERF_IP_FLAG_TRACE_END)) {
143099f753f0SAndi Kleen 		if (al->sym)
143199f753f0SAndi Kleen 			name = al->sym->name;
143299f753f0SAndi Kleen 		else
143399f753f0SAndi Kleen 			*ip = sample->ip;
143499f753f0SAndi Kleen 	}
143599f753f0SAndi Kleen 	return name;
143699f753f0SAndi Kleen }
143799f753f0SAndi Kleen 
perf_sample__fprintf_callindent(struct perf_sample * sample,struct evsel * evsel,struct thread * thread,struct addr_location * al,struct addr_location * addr_al,FILE * fp)1438a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_callindent(struct perf_sample *sample,
143932dcd021SJiri Olsa 					   struct evsel *evsel,
1440e216708dSAdrian Hunter 					   struct thread *thread,
1441b743b86cSAdrian Hunter 					   struct addr_location *al,
1442b743b86cSAdrian Hunter 					   struct addr_location *addr_al,
1443b743b86cSAdrian Hunter 					   FILE *fp)
1444e216708dSAdrian Hunter {
14451fc632ceSJiri Olsa 	struct perf_event_attr *attr = &evsel->core.attr;
1446256d92bcSAdrian Hunter 	size_t depth = thread_stack__depth(thread, sample->cpu);
1447e216708dSAdrian Hunter 	const char *name = NULL;
1448e216708dSAdrian Hunter 	static int spacing;
1449e216708dSAdrian Hunter 	int len = 0;
1450a78cdee6SAndi Kleen 	int dlen = 0;
1451e216708dSAdrian Hunter 	u64 ip = 0;
1452e216708dSAdrian Hunter 
1453e216708dSAdrian Hunter 	/*
1454e216708dSAdrian Hunter 	 * The 'return' has already been popped off the stack so the depth has
1455e216708dSAdrian Hunter 	 * to be adjusted to match the 'call'.
1456e216708dSAdrian Hunter 	 */
1457ee84a303SIan Rogers 	if (thread__ts(thread) && sample->flags & PERF_IP_FLAG_RETURN)
1458e216708dSAdrian Hunter 		depth += 1;
1459e216708dSAdrian Hunter 
1460b743b86cSAdrian Hunter 	name = resolve_branch_sym(sample, evsel, thread, al, addr_al, &ip);
1461e216708dSAdrian Hunter 
1462a78cdee6SAndi Kleen 	if (PRINT_FIELD(DSO) && !(PRINT_FIELD(IP) || PRINT_FIELD(ADDR))) {
1463a78cdee6SAndi Kleen 		dlen += fprintf(fp, "(");
1464a78cdee6SAndi Kleen 		dlen += map__fprintf_dsoname(al->map, fp);
1465a78cdee6SAndi Kleen 		dlen += fprintf(fp, ")\t");
1466a78cdee6SAndi Kleen 	}
1467a78cdee6SAndi Kleen 
1468e216708dSAdrian Hunter 	if (name)
1469a1a58707SArnaldo Carvalho de Melo 		len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);
1470e216708dSAdrian Hunter 	else if (ip)
1471a1a58707SArnaldo Carvalho de Melo 		len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip);
1472e216708dSAdrian Hunter 
1473e216708dSAdrian Hunter 	if (len < 0)
1474a1a58707SArnaldo Carvalho de Melo 		return len;
1475e216708dSAdrian Hunter 
1476e216708dSAdrian Hunter 	/*
1477e216708dSAdrian Hunter 	 * Try to keep the output length from changing frequently so that the
1478e216708dSAdrian Hunter 	 * output lines up more nicely.
1479e216708dSAdrian Hunter 	 */
1480e216708dSAdrian Hunter 	if (len > spacing || (len && len < spacing - 52))
1481e216708dSAdrian Hunter 		spacing = round_up(len + 4, 32);
1482e216708dSAdrian Hunter 
1483e216708dSAdrian Hunter 	if (len < spacing)
1484a1a58707SArnaldo Carvalho de Melo 		len += fprintf(fp, "%*s", spacing - len, "");
1485a1a58707SArnaldo Carvalho de Melo 
1486a78cdee6SAndi Kleen 	return len + dlen;
1487e216708dSAdrian Hunter }
1488e216708dSAdrian Hunter 
arch_fetch_insn(struct perf_sample * sample __maybe_unused,struct thread * thread __maybe_unused,struct machine * machine __maybe_unused)14893ab481a1SAndi Kleen __weak void arch_fetch_insn(struct perf_sample *sample __maybe_unused,
14903ab481a1SAndi Kleen 			    struct thread *thread __maybe_unused,
14913ab481a1SAndi Kleen 			    struct machine *machine __maybe_unused)
14923ab481a1SAndi Kleen {
14933ab481a1SAndi Kleen }
14943ab481a1SAndi Kleen 
script_fetch_insn(struct perf_sample * sample,struct thread * thread,struct machine * machine)1495d9ae9c97SAdrian Hunter void script_fetch_insn(struct perf_sample *sample, struct thread *thread,
1496d9ae9c97SAdrian Hunter 		       struct machine *machine)
1497d9ae9c97SAdrian Hunter {
1498d9ae9c97SAdrian Hunter 	if (sample->insn_len == 0 && native_arch)
1499d9ae9c97SAdrian Hunter 		arch_fetch_insn(sample, thread, machine);
1500d9ae9c97SAdrian Hunter }
1501d9ae9c97SAdrian Hunter 
perf_sample__fprintf_insn(struct perf_sample * sample,struct perf_event_attr * attr,struct thread * thread,struct machine * machine,FILE * fp)1502a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_insn(struct perf_sample *sample,
150348d02a1dSAndi Kleen 				     struct perf_event_attr *attr,
150448d02a1dSAndi Kleen 				     struct thread *thread,
1505a1a58707SArnaldo Carvalho de Melo 				     struct machine *machine, FILE *fp)
1506224e2c97SAndi Kleen {
1507a1a58707SArnaldo Carvalho de Melo 	int printed = 0;
1508a1a58707SArnaldo Carvalho de Melo 
1509d9ae9c97SAdrian Hunter 	script_fetch_insn(sample, thread, machine);
15103ab481a1SAndi Kleen 
1511224e2c97SAndi Kleen 	if (PRINT_FIELD(INSNLEN))
1512a1a58707SArnaldo Carvalho de Melo 		printed += fprintf(fp, " ilen: %d", sample->insn_len);
15133ab481a1SAndi Kleen 	if (PRINT_FIELD(INSN) && sample->insn_len) {
1514224e2c97SAndi Kleen 		int i;
1515224e2c97SAndi Kleen 
1516a1a58707SArnaldo Carvalho de Melo 		printed += fprintf(fp, " insn:");
1517224e2c97SAndi Kleen 		for (i = 0; i < sample->insn_len; i++)
1518a1a58707SArnaldo Carvalho de Melo 			printed += fprintf(fp, " %02x", (unsigned char)sample->insn[i]);
1519224e2c97SAndi Kleen 	}
15206f680c6aSKan Liang 	if (PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN))
1521a1a58707SArnaldo Carvalho de Melo 		printed += perf_sample__fprintf_brstackinsn(sample, thread, attr, machine, fp);
1522a1a58707SArnaldo Carvalho de Melo 
1523a1a58707SArnaldo Carvalho de Melo 	return printed;
1524224e2c97SAndi Kleen }
1525224e2c97SAndi Kleen 
perf_sample__fprintf_ipc(struct perf_sample * sample,struct perf_event_attr * attr,FILE * fp)152668fb45bfSAdrian Hunter static int perf_sample__fprintf_ipc(struct perf_sample *sample,
152768fb45bfSAdrian Hunter 				    struct perf_event_attr *attr, FILE *fp)
152868fb45bfSAdrian Hunter {
152968fb45bfSAdrian Hunter 	unsigned int ipc;
153068fb45bfSAdrian Hunter 
153168fb45bfSAdrian Hunter 	if (!PRINT_FIELD(IPC) || !sample->cyc_cnt || !sample->insn_cnt)
153268fb45bfSAdrian Hunter 		return 0;
153368fb45bfSAdrian Hunter 
153468fb45bfSAdrian Hunter 	ipc = (sample->insn_cnt * 100) / sample->cyc_cnt;
153568fb45bfSAdrian Hunter 
153668fb45bfSAdrian Hunter 	return fprintf(fp, " \t IPC: %u.%02u (%" PRIu64 "/%" PRIu64 ") ",
153768fb45bfSAdrian Hunter 		       ipc / 100, ipc % 100, sample->insn_cnt, sample->cyc_cnt);
153868fb45bfSAdrian Hunter }
153968fb45bfSAdrian Hunter 
perf_sample__fprintf_bts(struct perf_sample * sample,struct evsel * evsel,struct thread * thread,struct addr_location * al,struct addr_location * addr_al,struct machine * machine,FILE * fp)1540a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_bts(struct perf_sample *sample,
154132dcd021SJiri Olsa 				    struct evsel *evsel,
1542a2cb3cf2SAdrian Hunter 				    struct thread *thread,
154348d02a1dSAndi Kleen 				    struct addr_location *al,
1544b743b86cSAdrian Hunter 				    struct addr_location *addr_al,
1545a1a58707SArnaldo Carvalho de Melo 				    struct machine *machine, FILE *fp)
154695582596SAkihiro Nagai {
15471fc632ceSJiri Olsa 	struct perf_event_attr *attr = &evsel->core.attr;
15481405720dSAdrian Hunter 	unsigned int type = output_type(attr->type);
15498066be5fSAdrian Hunter 	bool print_srcline_last = false;
1550a1a58707SArnaldo Carvalho de Melo 	int printed = 0;
155195582596SAkihiro Nagai 
1552e216708dSAdrian Hunter 	if (PRINT_FIELD(CALLINDENT))
1553b743b86cSAdrian Hunter 		printed += perf_sample__fprintf_callindent(sample, evsel, thread, al, addr_al, fp);
1554e216708dSAdrian Hunter 
155595582596SAkihiro Nagai 	/* print branch_from information */
155695582596SAkihiro Nagai 	if (PRINT_FIELD(IP)) {
15571405720dSAdrian Hunter 		unsigned int print_opts = output[type].print_ip_opts;
1558e557b674SChris Phlipot 		struct callchain_cursor *cursor = NULL;
15598066be5fSAdrian Hunter 
15608ab12a20SIan Rogers 		if (symbol_conf.use_callchain && sample->callchain) {
15618ab12a20SIan Rogers 			cursor = get_tls_callchain_cursor();
15628ab12a20SIan Rogers 			if (thread__resolve_callchain(al->thread, cursor, evsel,
15638ab12a20SIan Rogers 						      sample, NULL, NULL,
15648ab12a20SIan Rogers 						      scripting_max_stack))
15658ab12a20SIan Rogers 				cursor = NULL;
15668ab12a20SIan Rogers 		}
15676f736735SArnaldo Carvalho de Melo 		if (cursor == NULL) {
1568a1a58707SArnaldo Carvalho de Melo 			printed += fprintf(fp, " ");
1569e20ab86eSArnaldo Carvalho de Melo 			if (print_opts & EVSEL__PRINT_SRCLINE) {
15708066be5fSAdrian Hunter 				print_srcline_last = true;
1571e20ab86eSArnaldo Carvalho de Melo 				print_opts &= ~EVSEL__PRINT_SRCLINE;
15728066be5fSAdrian Hunter 			}
15736f736735SArnaldo Carvalho de Melo 		} else
1574a1a58707SArnaldo Carvalho de Melo 			printed += fprintf(fp, "\n");
15756f736735SArnaldo Carvalho de Melo 
15769620bc36SArnaldo Carvalho de Melo 		printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor,
15779620bc36SArnaldo Carvalho de Melo 					       symbol_conf.bt_stop_list, fp);
157895582596SAkihiro Nagai 	}
157995582596SAkihiro Nagai 
158095582596SAkihiro Nagai 	/* print branch_to information */
1581243be3ddSAdrian Hunter 	if (PRINT_FIELD(ADDR) ||
15821fc632ceSJiri Olsa 	    ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
15831405720dSAdrian Hunter 	     !output[type].user_set)) {
1584a1a58707SArnaldo Carvalho de Melo 		printed += fprintf(fp, " => ");
1585a1a58707SArnaldo Carvalho de Melo 		printed += perf_sample__fprintf_addr(sample, thread, attr, fp);
1586578bea40SAdrian Hunter 	}
158795582596SAkihiro Nagai 
158868fb45bfSAdrian Hunter 	printed += perf_sample__fprintf_ipc(sample, attr, fp);
158968fb45bfSAdrian Hunter 
15908066be5fSAdrian Hunter 	if (print_srcline_last)
1591a1a58707SArnaldo Carvalho de Melo 		printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
15928066be5fSAdrian Hunter 
1593a1a58707SArnaldo Carvalho de Melo 	printed += perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
1594dd2e18e9SAndi Kleen 	printed += fprintf(fp, "\n");
1595dd2e18e9SAndi Kleen 	if (PRINT_FIELD(SRCCODE)) {
1596dd2e18e9SAndi Kleen 		int ret = map__fprintf_srccode(al->map, al->addr, stdout,
1597ee84a303SIan Rogers 					       thread__srccode_state(thread));
1598dd2e18e9SAndi Kleen 		if (ret) {
1599dd2e18e9SAndi Kleen 			printed += ret;
1600dd2e18e9SAndi Kleen 			printed += printf("\n");
1601dd2e18e9SAndi Kleen 		}
1602dd2e18e9SAndi Kleen 	}
1603dd2e18e9SAndi Kleen 	return printed;
160495582596SAkihiro Nagai }
160595582596SAkihiro Nagai 
1606055cd33dSAdrian Hunter static struct {
1607055cd33dSAdrian Hunter 	u32 flags;
1608055cd33dSAdrian Hunter 	const char *name;
1609055cd33dSAdrian Hunter } sample_flags[] = {
1610055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},
1611055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},
1612055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"},
1613055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH, "jmp"},
1614055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"},
1615055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"},
1616055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"},
1617055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"},
1618055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"},
1619055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |	PERF_IP_FLAG_INTERRUPT, "hw int"},
1620055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"},
1621055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"},
1622055cd33dSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"},
1623c025d46cSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMENTRY, "vmentry"},
1624c025d46cSAdrian Hunter 	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMEXIT, "vmexit"},
1625055cd33dSAdrian Hunter 	{0, NULL}
1626055cd33dSAdrian Hunter };
1627055cd33dSAdrian Hunter 
sample_flags_to_name(u32 flags)162862cb1b88SAdrian Hunter static const char *sample_flags_to_name(u32 flags)
162962cb1b88SAdrian Hunter {
163062cb1b88SAdrian Hunter 	int i;
163162cb1b88SAdrian Hunter 
163262cb1b88SAdrian Hunter 	for (i = 0; sample_flags[i].name ; i++) {
163362cb1b88SAdrian Hunter 		if (sample_flags[i].flags == flags)
163462cb1b88SAdrian Hunter 			return sample_flags[i].name;
163562cb1b88SAdrian Hunter 	}
163662cb1b88SAdrian Hunter 
163762cb1b88SAdrian Hunter 	return NULL;
163862cb1b88SAdrian Hunter }
163962cb1b88SAdrian Hunter 
perf_sample__sprintf_flags(u32 flags,char * str,size_t sz)164054cd8b03SAdrian Hunter int perf_sample__sprintf_flags(u32 flags, char *str, size_t sz)
1641400ea6d3SAdrian Hunter {
164226738598SAdrian Hunter 	u32 xf = PERF_IP_FLAG_IN_TX | PERF_IP_FLAG_INTR_DISABLE |
164326738598SAdrian Hunter 		 PERF_IP_FLAG_INTR_TOGGLE;
1644400ea6d3SAdrian Hunter 	const char *chars = PERF_IP_FLAG_CHARS;
164554cd8b03SAdrian Hunter 	const size_t n = strlen(PERF_IP_FLAG_CHARS);
1646055cd33dSAdrian Hunter 	const char *name = NULL;
164754cd8b03SAdrian Hunter 	size_t i, pos = 0;
164826738598SAdrian Hunter 	char xs[16] = {0};
1649400ea6d3SAdrian Hunter 
165026738598SAdrian Hunter 	if (flags & xf)
165126738598SAdrian Hunter 		snprintf(xs, sizeof(xs), "(%s%s%s)",
165226738598SAdrian Hunter 			 flags & PERF_IP_FLAG_IN_TX ? "x" : "",
165326738598SAdrian Hunter 			 flags & PERF_IP_FLAG_INTR_DISABLE ? "D" : "",
165426738598SAdrian Hunter 			 flags & PERF_IP_FLAG_INTR_TOGGLE ? "t" : "");
165526738598SAdrian Hunter 
165626738598SAdrian Hunter 	name = sample_flags_to_name(flags & ~xf);
165762cb1b88SAdrian Hunter 	if (name)
165826738598SAdrian Hunter 		return snprintf(str, sz, "%-15s%6s", name, xs);
165962cb1b88SAdrian Hunter 
166062cb1b88SAdrian Hunter 	if (flags & PERF_IP_FLAG_TRACE_BEGIN) {
166126738598SAdrian Hunter 		name = sample_flags_to_name(flags & ~(xf | PERF_IP_FLAG_TRACE_BEGIN));
166262cb1b88SAdrian Hunter 		if (name)
166326738598SAdrian Hunter 			return snprintf(str, sz, "tr strt %-7s%6s", name, xs);
1664055cd33dSAdrian Hunter 	}
166562cb1b88SAdrian Hunter 
166662cb1b88SAdrian Hunter 	if (flags & PERF_IP_FLAG_TRACE_END) {
166726738598SAdrian Hunter 		name = sample_flags_to_name(flags & ~(xf | PERF_IP_FLAG_TRACE_END));
166862cb1b88SAdrian Hunter 		if (name)
166926738598SAdrian Hunter 			return snprintf(str, sz, "tr end  %-7s%6s", name, xs);
1670055cd33dSAdrian Hunter 	}
1671055cd33dSAdrian Hunter 
1672400ea6d3SAdrian Hunter 	for (i = 0; i < n; i++, flags >>= 1) {
167354cd8b03SAdrian Hunter 		if ((flags & 1) && pos < sz)
1674400ea6d3SAdrian Hunter 			str[pos++] = chars[i];
1675400ea6d3SAdrian Hunter 	}
1676400ea6d3SAdrian Hunter 	for (; i < 32; i++, flags >>= 1) {
167754cd8b03SAdrian Hunter 		if ((flags & 1) && pos < sz)
1678400ea6d3SAdrian Hunter 			str[pos++] = '?';
1679400ea6d3SAdrian Hunter 	}
168054cd8b03SAdrian Hunter 	if (pos < sz)
1681400ea6d3SAdrian Hunter 		str[pos] = 0;
1682055cd33dSAdrian Hunter 
168354cd8b03SAdrian Hunter 	return pos;
168454cd8b03SAdrian Hunter }
168554cd8b03SAdrian Hunter 
perf_sample__fprintf_flags(u32 flags,FILE * fp)168654cd8b03SAdrian Hunter static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
168754cd8b03SAdrian Hunter {
168854cd8b03SAdrian Hunter 	char str[SAMPLE_FLAGS_BUF_SIZE];
168954cd8b03SAdrian Hunter 
169054cd8b03SAdrian Hunter 	perf_sample__sprintf_flags(flags, str, sizeof(str));
169126738598SAdrian Hunter 	return fprintf(fp, "  %-21s ", str);
1692400ea6d3SAdrian Hunter }
1693400ea6d3SAdrian Hunter 
169430372f04SWang Nan struct printer_data {
169530372f04SWang Nan 	int line_no;
169630372f04SWang Nan 	bool hit_nul;
169730372f04SWang Nan 	bool is_printable;
169830372f04SWang Nan };
169930372f04SWang Nan 
sample__fprintf_bpf_output(enum binary_printer_ops op,unsigned int val,void * extra,FILE * fp)1700923d0c9aSArnaldo Carvalho de Melo static int sample__fprintf_bpf_output(enum binary_printer_ops op,
170130372f04SWang Nan 				      unsigned int val,
1702923d0c9aSArnaldo Carvalho de Melo 				      void *extra, FILE *fp)
170330372f04SWang Nan {
170430372f04SWang Nan 	unsigned char ch = (unsigned char)val;
170530372f04SWang Nan 	struct printer_data *printer_data = extra;
1706923d0c9aSArnaldo Carvalho de Melo 	int printed = 0;
170730372f04SWang Nan 
170830372f04SWang Nan 	switch (op) {
170930372f04SWang Nan 	case BINARY_PRINT_DATA_BEGIN:
1710923d0c9aSArnaldo Carvalho de Melo 		printed += fprintf(fp, "\n");
171130372f04SWang Nan 		break;
171230372f04SWang Nan 	case BINARY_PRINT_LINE_BEGIN:
1713923d0c9aSArnaldo Carvalho de Melo 		printed += fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" :
171430372f04SWang Nan 						        "           ");
171530372f04SWang Nan 		break;
171630372f04SWang Nan 	case BINARY_PRINT_ADDR:
1717923d0c9aSArnaldo Carvalho de Melo 		printed += fprintf(fp, " %04x:", val);
171830372f04SWang Nan 		break;
171930372f04SWang Nan 	case BINARY_PRINT_NUM_DATA:
1720923d0c9aSArnaldo Carvalho de Melo 		printed += fprintf(fp, " %02x", val);
172130372f04SWang Nan 		break;
172230372f04SWang Nan 	case BINARY_PRINT_NUM_PAD:
1723923d0c9aSArnaldo Carvalho de Melo 		printed += fprintf(fp, "   ");
172430372f04SWang Nan 		break;
172530372f04SWang Nan 	case BINARY_PRINT_SEP:
1726923d0c9aSArnaldo Carvalho de Melo 		printed += fprintf(fp, "  ");
172730372f04SWang Nan 		break;
172830372f04SWang Nan 	case BINARY_PRINT_CHAR_DATA:
172930372f04SWang Nan 		if (printer_data->hit_nul && ch)
173030372f04SWang Nan 			printer_data->is_printable = false;
173130372f04SWang Nan 
173230372f04SWang Nan 		if (!isprint(ch)) {
1733923d0c9aSArnaldo Carvalho de Melo 			printed += fprintf(fp, "%c", '.');
173430372f04SWang Nan 
173530372f04SWang Nan 			if (!printer_data->is_printable)
173630372f04SWang Nan 				break;
173730372f04SWang Nan 
173830372f04SWang Nan 			if (ch == '\0')
173930372f04SWang Nan 				printer_data->hit_nul = true;
174030372f04SWang Nan 			else
174130372f04SWang Nan 				printer_data->is_printable = false;
174230372f04SWang Nan 		} else {
1743923d0c9aSArnaldo Carvalho de Melo 			printed += fprintf(fp, "%c", ch);
174430372f04SWang Nan 		}
174530372f04SWang Nan 		break;
174630372f04SWang Nan 	case BINARY_PRINT_CHAR_PAD:
1747923d0c9aSArnaldo Carvalho de Melo 		printed += fprintf(fp, " ");
174830372f04SWang Nan 		break;
174930372f04SWang Nan 	case BINARY_PRINT_LINE_END:
1750923d0c9aSArnaldo Carvalho de Melo 		printed += fprintf(fp, "\n");
175130372f04SWang Nan 		printer_data->line_no++;
175230372f04SWang Nan 		break;
175330372f04SWang Nan 	case BINARY_PRINT_DATA_END:
175430372f04SWang Nan 	default:
175530372f04SWang Nan 		break;
175630372f04SWang Nan 	}
1757923d0c9aSArnaldo Carvalho de Melo 
1758923d0c9aSArnaldo Carvalho de Melo 	return printed;
175930372f04SWang Nan }
176030372f04SWang Nan 
perf_sample__fprintf_bpf_output(struct perf_sample * sample,FILE * fp)1761a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_bpf_output(struct perf_sample *sample, FILE *fp)
176230372f04SWang Nan {
176330372f04SWang Nan 	unsigned int nr_bytes = sample->raw_size;
176430372f04SWang Nan 	struct printer_data printer_data = {0, false, true};
1765a1a58707SArnaldo Carvalho de Melo 	int printed = binary__fprintf(sample->raw_data, nr_bytes, 8,
1766a1a58707SArnaldo Carvalho de Melo 				      sample__fprintf_bpf_output, &printer_data, fp);
176730372f04SWang Nan 
176830372f04SWang Nan 	if (printer_data.is_printable && printer_data.hit_nul)
1769a1a58707SArnaldo Carvalho de Melo 		printed += fprintf(fp, "%17s \"%s\"\n", "BPF string:", (char *)(sample->raw_data));
1770a1a58707SArnaldo Carvalho de Melo 
1771a1a58707SArnaldo Carvalho de Melo 	return printed;
177230372f04SWang Nan }
177330372f04SWang Nan 
perf_sample__fprintf_spacing(int len,int spacing,FILE * fp)1774a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp)
177565c5e18fSAdrian Hunter {
177665c5e18fSAdrian Hunter 	if (len > 0 && len < spacing)
1777a1a58707SArnaldo Carvalho de Melo 		return fprintf(fp, "%*s", spacing - len, "");
1778a1a58707SArnaldo Carvalho de Melo 
1779a1a58707SArnaldo Carvalho de Melo 	return 0;
178065c5e18fSAdrian Hunter }
178165c5e18fSAdrian Hunter 
perf_sample__fprintf_pt_spacing(int len,FILE * fp)1782a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)
178365c5e18fSAdrian Hunter {
1784a1a58707SArnaldo Carvalho de Melo 	return perf_sample__fprintf_spacing(len, 34, fp);
178565c5e18fSAdrian Hunter }
178665c5e18fSAdrian Hunter 
1787a5014310SAdrian Hunter /* If a value contains only printable ASCII characters padded with NULLs */
ptw_is_prt(u64 val)1788a5014310SAdrian Hunter static bool ptw_is_prt(u64 val)
1789a5014310SAdrian Hunter {
1790a5014310SAdrian Hunter 	char c;
1791a5014310SAdrian Hunter 	u32 i;
1792a5014310SAdrian Hunter 
1793a5014310SAdrian Hunter 	for (i = 0; i < sizeof(val); i++) {
1794a5014310SAdrian Hunter 		c = ((char *)&val)[i];
1795a5014310SAdrian Hunter 		if (!c)
1796a5014310SAdrian Hunter 			break;
1797a5014310SAdrian Hunter 		if (!isprint(c) || !isascii(c))
1798a5014310SAdrian Hunter 			return false;
1799a5014310SAdrian Hunter 	}
1800a5014310SAdrian Hunter 	for (; i < sizeof(val); i++) {
1801a5014310SAdrian Hunter 		c = ((char *)&val)[i];
1802a5014310SAdrian Hunter 		if (c)
1803a5014310SAdrian Hunter 			return false;
1804a5014310SAdrian Hunter 	}
1805a5014310SAdrian Hunter 	return true;
1806a5014310SAdrian Hunter }
1807a5014310SAdrian Hunter 
perf_sample__fprintf_synth_ptwrite(struct perf_sample * sample,FILE * fp)1808a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp)
180965c5e18fSAdrian Hunter {
181065c5e18fSAdrian Hunter 	struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
1811a5014310SAdrian Hunter 	char str[sizeof(u64) + 1] = "";
181265c5e18fSAdrian Hunter 	int len;
1813a5014310SAdrian Hunter 	u64 val;
181465c5e18fSAdrian Hunter 
181565c5e18fSAdrian Hunter 	if (perf_sample__bad_synth_size(sample, *data))
1816a1a58707SArnaldo Carvalho de Melo 		return 0;
181765c5e18fSAdrian Hunter 
1818a5014310SAdrian Hunter 	val = le64_to_cpu(data->payload);
1819a5014310SAdrian Hunter 	if (ptw_is_prt(val)) {
1820a5014310SAdrian Hunter 		memcpy(str, &val, sizeof(val));
1821a5014310SAdrian Hunter 		str[sizeof(val)] = 0;
1822a5014310SAdrian Hunter 	}
1823a5014310SAdrian Hunter 	len = fprintf(fp, " IP: %u payload: %#" PRIx64 " %s ",
1824a5014310SAdrian Hunter 		      data->ip, val, str);
1825a1a58707SArnaldo Carvalho de Melo 	return len + perf_sample__fprintf_pt_spacing(len, fp);
182665c5e18fSAdrian Hunter }
182765c5e18fSAdrian Hunter 
perf_sample__fprintf_synth_mwait(struct perf_sample * sample,FILE * fp)1828a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_synth_mwait(struct perf_sample *sample, FILE *fp)
182965c5e18fSAdrian Hunter {
183065c5e18fSAdrian Hunter 	struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
183165c5e18fSAdrian Hunter 	int len;
183265c5e18fSAdrian Hunter 
183365c5e18fSAdrian Hunter 	if (perf_sample__bad_synth_size(sample, *data))
1834a1a58707SArnaldo Carvalho de Melo 		return 0;
183565c5e18fSAdrian Hunter 
1836a1a58707SArnaldo Carvalho de Melo 	len = fprintf(fp, " hints: %#x extensions: %#x ",
183765c5e18fSAdrian Hunter 		      data->hints, data->extensions);
1838a1a58707SArnaldo Carvalho de Melo 	return len + perf_sample__fprintf_pt_spacing(len, fp);
183965c5e18fSAdrian Hunter }
184065c5e18fSAdrian Hunter 
perf_sample__fprintf_synth_pwre(struct perf_sample * sample,FILE * fp)1841a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_synth_pwre(struct perf_sample *sample, FILE *fp)
184265c5e18fSAdrian Hunter {
184365c5e18fSAdrian Hunter 	struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
184465c5e18fSAdrian Hunter 	int len;
184565c5e18fSAdrian Hunter 
184665c5e18fSAdrian Hunter 	if (perf_sample__bad_synth_size(sample, *data))
1847a1a58707SArnaldo Carvalho de Melo 		return 0;
184865c5e18fSAdrian Hunter 
1849a1a58707SArnaldo Carvalho de Melo 	len = fprintf(fp, " hw: %u cstate: %u sub-cstate: %u ",
185065c5e18fSAdrian Hunter 		      data->hw, data->cstate, data->subcstate);
1851a1a58707SArnaldo Carvalho de Melo 	return len + perf_sample__fprintf_pt_spacing(len, fp);
185265c5e18fSAdrian Hunter }
185365c5e18fSAdrian Hunter 
perf_sample__fprintf_synth_exstop(struct perf_sample * sample,FILE * fp)1854a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_synth_exstop(struct perf_sample *sample, FILE *fp)
185565c5e18fSAdrian Hunter {
185665c5e18fSAdrian Hunter 	struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
185765c5e18fSAdrian Hunter 	int len;
185865c5e18fSAdrian Hunter 
185965c5e18fSAdrian Hunter 	if (perf_sample__bad_synth_size(sample, *data))
1860a1a58707SArnaldo Carvalho de Melo 		return 0;
186165c5e18fSAdrian Hunter 
1862a1a58707SArnaldo Carvalho de Melo 	len = fprintf(fp, " IP: %u ", data->ip);
1863a1a58707SArnaldo Carvalho de Melo 	return len + perf_sample__fprintf_pt_spacing(len, fp);
186465c5e18fSAdrian Hunter }
186565c5e18fSAdrian Hunter 
perf_sample__fprintf_synth_pwrx(struct perf_sample * sample,FILE * fp)1866a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_synth_pwrx(struct perf_sample *sample, FILE *fp)
186765c5e18fSAdrian Hunter {
186865c5e18fSAdrian Hunter 	struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
186965c5e18fSAdrian Hunter 	int len;
187065c5e18fSAdrian Hunter 
187165c5e18fSAdrian Hunter 	if (perf_sample__bad_synth_size(sample, *data))
1872a1a58707SArnaldo Carvalho de Melo 		return 0;
187365c5e18fSAdrian Hunter 
1874a1a58707SArnaldo Carvalho de Melo 	len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ",
187565c5e18fSAdrian Hunter 		     data->deepest_cstate, data->last_cstate,
187665c5e18fSAdrian Hunter 		     data->wake_reason);
1877a1a58707SArnaldo Carvalho de Melo 	return len + perf_sample__fprintf_pt_spacing(len, fp);
187865c5e18fSAdrian Hunter }
187965c5e18fSAdrian Hunter 
perf_sample__fprintf_synth_cbr(struct perf_sample * sample,FILE * fp)1880a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp)
188165c5e18fSAdrian Hunter {
188265c5e18fSAdrian Hunter 	struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample);
188365c5e18fSAdrian Hunter 	unsigned int percent, freq;
188465c5e18fSAdrian Hunter 	int len;
188565c5e18fSAdrian Hunter 
188665c5e18fSAdrian Hunter 	if (perf_sample__bad_synth_size(sample, *data))
1887a1a58707SArnaldo Carvalho de Melo 		return 0;
188865c5e18fSAdrian Hunter 
188965c5e18fSAdrian Hunter 	freq = (le32_to_cpu(data->freq) + 500) / 1000;
1890a1a58707SArnaldo Carvalho de Melo 	len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
189165c5e18fSAdrian Hunter 	if (data->max_nonturbo) {
189265c5e18fSAdrian Hunter 		percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
1893a1a58707SArnaldo Carvalho de Melo 		len += fprintf(fp, "(%3u%%) ", percent);
189465c5e18fSAdrian Hunter 	}
1895a1a58707SArnaldo Carvalho de Melo 	return len + perf_sample__fprintf_pt_spacing(len, fp);
189665c5e18fSAdrian Hunter }
189765c5e18fSAdrian Hunter 
perf_sample__fprintf_synth_psb(struct perf_sample * sample,FILE * fp)1898c840cbfeSAdrian Hunter static int perf_sample__fprintf_synth_psb(struct perf_sample *sample, FILE *fp)
1899c840cbfeSAdrian Hunter {
1900c840cbfeSAdrian Hunter 	struct perf_synth_intel_psb *data = perf_sample__synth_ptr(sample);
1901c840cbfeSAdrian Hunter 	int len;
1902c840cbfeSAdrian Hunter 
1903c840cbfeSAdrian Hunter 	if (perf_sample__bad_synth_size(sample, *data))
1904c840cbfeSAdrian Hunter 		return 0;
1905c840cbfeSAdrian Hunter 
1906c840cbfeSAdrian Hunter 	len = fprintf(fp, " psb offs: %#" PRIx64, data->offset);
1907c840cbfeSAdrian Hunter 	return len + perf_sample__fprintf_pt_spacing(len, fp);
1908c840cbfeSAdrian Hunter }
1909c840cbfeSAdrian Hunter 
19105b11749bSAdrian Hunter /* Intel PT Event Trace */
perf_sample__fprintf_synth_evt(struct perf_sample * sample,FILE * fp)19115b11749bSAdrian Hunter static int perf_sample__fprintf_synth_evt(struct perf_sample *sample, FILE *fp)
19125b11749bSAdrian Hunter {
19135b11749bSAdrian Hunter 	struct perf_synth_intel_evt *data = perf_sample__synth_ptr(sample);
19145b11749bSAdrian Hunter 	const char *cfe[32] = {NULL, "INTR", "IRET", "SMI", "RSM", "SIPI",
19155b11749bSAdrian Hunter 			       "INIT", "VMENTRY", "VMEXIT", "VMEXIT_INTR",
191634f576c9SAdrian Hunter 			       "SHUTDOWN", NULL, "UINTR", "UIRET"};
19175b11749bSAdrian Hunter 	const char *evd[64] = {"PFA", "VMXQ", "VMXR"};
19185b11749bSAdrian Hunter 	const char *s;
19195b11749bSAdrian Hunter 	int len, i;
19205b11749bSAdrian Hunter 
19215b11749bSAdrian Hunter 	if (perf_sample__bad_synth_size(sample, *data))
19225b11749bSAdrian Hunter 		return 0;
19235b11749bSAdrian Hunter 
19245b11749bSAdrian Hunter 	s = cfe[data->type];
19255b11749bSAdrian Hunter 	if (s) {
19265b11749bSAdrian Hunter 		len = fprintf(fp, " cfe: %s IP: %d vector: %u",
19275b11749bSAdrian Hunter 			      s, data->ip, data->vector);
19285b11749bSAdrian Hunter 	} else {
19295b11749bSAdrian Hunter 		len = fprintf(fp, " cfe: %u IP: %d vector: %u",
19305b11749bSAdrian Hunter 			      data->type, data->ip, data->vector);
19315b11749bSAdrian Hunter 	}
19325b11749bSAdrian Hunter 	for (i = 0; i < data->evd_cnt; i++) {
19335b11749bSAdrian Hunter 		unsigned int et = data->evd[i].evd_type & 0x3f;
19345b11749bSAdrian Hunter 
19355b11749bSAdrian Hunter 		s = evd[et];
19365b11749bSAdrian Hunter 		if (s) {
19375b11749bSAdrian Hunter 			len += fprintf(fp, " %s: %#" PRIx64,
19385b11749bSAdrian Hunter 				       s, data->evd[i].payload);
19395b11749bSAdrian Hunter 		} else {
19405b11749bSAdrian Hunter 			len += fprintf(fp, " EVD_%u: %#" PRIx64,
19415b11749bSAdrian Hunter 				       et, data->evd[i].payload);
19425b11749bSAdrian Hunter 		}
19435b11749bSAdrian Hunter 	}
19445b11749bSAdrian Hunter 	return len + perf_sample__fprintf_pt_spacing(len, fp);
19455b11749bSAdrian Hunter }
19465b11749bSAdrian Hunter 
perf_sample__fprintf_synth_iflag_chg(struct perf_sample * sample,FILE * fp)1947a48b96caSAdrian Hunter static int perf_sample__fprintf_synth_iflag_chg(struct perf_sample *sample, FILE *fp)
1948a48b96caSAdrian Hunter {
1949a48b96caSAdrian Hunter 	struct perf_synth_intel_iflag_chg *data = perf_sample__synth_ptr(sample);
1950a48b96caSAdrian Hunter 	int len;
1951a48b96caSAdrian Hunter 
1952a48b96caSAdrian Hunter 	if (perf_sample__bad_synth_size(sample, *data))
1953a48b96caSAdrian Hunter 		return 0;
1954a48b96caSAdrian Hunter 
1955a48b96caSAdrian Hunter 	len = fprintf(fp, " IFLAG: %d->%d %s branch", !data->iflag, data->iflag,
1956a48b96caSAdrian Hunter 		      data->via_branch ? "via" : "non");
1957a48b96caSAdrian Hunter 	return len + perf_sample__fprintf_pt_spacing(len, fp);
1958a48b96caSAdrian Hunter }
1959a48b96caSAdrian Hunter 
perf_sample__fprintf_synth(struct perf_sample * sample,struct evsel * evsel,FILE * fp)1960a1a58707SArnaldo Carvalho de Melo static int perf_sample__fprintf_synth(struct perf_sample *sample,
196132dcd021SJiri Olsa 				      struct evsel *evsel, FILE *fp)
196247e78084SAdrian Hunter {
19631fc632ceSJiri Olsa 	switch (evsel->core.attr.config) {
196465c5e18fSAdrian Hunter 	case PERF_SYNTH_INTEL_PTWRITE:
1965a1a58707SArnaldo Carvalho de Melo 		return perf_sample__fprintf_synth_ptwrite(sample, fp);
196665c5e18fSAdrian Hunter 	case PERF_SYNTH_INTEL_MWAIT:
1967a1a58707SArnaldo Carvalho de Melo 		return perf_sample__fprintf_synth_mwait(sample, fp);
196865c5e18fSAdrian Hunter 	case PERF_SYNTH_INTEL_PWRE:
1969a1a58707SArnaldo Carvalho de Melo 		return perf_sample__fprintf_synth_pwre(sample, fp);
197065c5e18fSAdrian Hunter 	case PERF_SYNTH_INTEL_EXSTOP:
1971a1a58707SArnaldo Carvalho de Melo 		return perf_sample__fprintf_synth_exstop(sample, fp);
197265c5e18fSAdrian Hunter 	case PERF_SYNTH_INTEL_PWRX:
1973a1a58707SArnaldo Carvalho de Melo 		return perf_sample__fprintf_synth_pwrx(sample, fp);
197465c5e18fSAdrian Hunter 	case PERF_SYNTH_INTEL_CBR:
1975a1a58707SArnaldo Carvalho de Melo 		return perf_sample__fprintf_synth_cbr(sample, fp);
1976c840cbfeSAdrian Hunter 	case PERF_SYNTH_INTEL_PSB:
1977c840cbfeSAdrian Hunter 		return perf_sample__fprintf_synth_psb(sample, fp);
19785b11749bSAdrian Hunter 	case PERF_SYNTH_INTEL_EVT:
19795b11749bSAdrian Hunter 		return perf_sample__fprintf_synth_evt(sample, fp);
1980a48b96caSAdrian Hunter 	case PERF_SYNTH_INTEL_IFLAG_CHG:
1981a48b96caSAdrian Hunter 		return perf_sample__fprintf_synth_iflag_chg(sample, fp);
198247e78084SAdrian Hunter 	default:
198347e78084SAdrian Hunter 		break;
198447e78084SAdrian Hunter 	}
1985a1a58707SArnaldo Carvalho de Melo 
1986a1a58707SArnaldo Carvalho de Melo 	return 0;
198747e78084SAdrian Hunter }
198847e78084SAdrian Hunter 
evlist__max_name_len(struct evlist * evlist)1989afdd63f5SArnaldo Carvalho de Melo static int evlist__max_name_len(struct evlist *evlist)
19909cdbc409SJiri Olsa {
199132dcd021SJiri Olsa 	struct evsel *evsel;
19929cdbc409SJiri Olsa 	int max = 0;
19939cdbc409SJiri Olsa 
1994e5cadb93SArnaldo Carvalho de Melo 	evlist__for_each_entry(evlist, evsel) {
19958ab2e96dSArnaldo Carvalho de Melo 		int len = strlen(evsel__name(evsel));
19969cdbc409SJiri Olsa 
19979cdbc409SJiri Olsa 		max = MAX(len, max);
19989cdbc409SJiri Olsa 	}
19999cdbc409SJiri Olsa 
20009cdbc409SJiri Olsa 	return max;
20019cdbc409SJiri Olsa }
20029cdbc409SJiri Olsa 
data_src__fprintf(u64 data_src,FILE * fp)2003a1a58707SArnaldo Carvalho de Melo static int data_src__fprintf(u64 data_src, FILE *fp)
2004c19ac912SJiri Olsa {
2005c19ac912SJiri Olsa 	struct mem_info mi = { .data_src.val = data_src };
2006c19ac912SJiri Olsa 	char decode[100];
2007c19ac912SJiri Olsa 	char out[100];
2008c19ac912SJiri Olsa 	static int maxlen;
2009c19ac912SJiri Olsa 	int len;
2010c19ac912SJiri Olsa 
2011c19ac912SJiri Olsa 	perf_script__meminfo_scnprintf(decode, 100, &mi);
2012c19ac912SJiri Olsa 
2013c19ac912SJiri Olsa 	len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode);
2014c19ac912SJiri Olsa 	if (maxlen < len)
2015c19ac912SJiri Olsa 		maxlen = len;
2016c19ac912SJiri Olsa 
2017a1a58707SArnaldo Carvalho de Melo 	return fprintf(fp, "%-*s", maxlen, out);
2018c19ac912SJiri Olsa }
2019c19ac912SJiri Olsa 
20204bd1bef8SAndi Kleen struct metric_ctx {
20214bd1bef8SAndi Kleen 	struct perf_sample	*sample;
20224bd1bef8SAndi Kleen 	struct thread		*thread;
202332dcd021SJiri Olsa 	struct evsel	*evsel;
20244bd1bef8SAndi Kleen 	FILE 			*fp;
20254bd1bef8SAndi Kleen };
20264bd1bef8SAndi Kleen 
script_print_metric(struct perf_stat_config * config __maybe_unused,void * ctx,const char * color,const char * fmt,const char * unit,double val)20276ca9a082SJiri Olsa static void script_print_metric(struct perf_stat_config *config __maybe_unused,
20286ca9a082SJiri Olsa 				void *ctx, const char *color,
20294bd1bef8SAndi Kleen 			        const char *fmt,
20304bd1bef8SAndi Kleen 			        const char *unit, double val)
20314bd1bef8SAndi Kleen {
20324bd1bef8SAndi Kleen 	struct metric_ctx *mctx = ctx;
20334bd1bef8SAndi Kleen 
20344bd1bef8SAndi Kleen 	if (!fmt)
20354bd1bef8SAndi Kleen 		return;
2036e534bfb1SJiri Olsa 	perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
203728a0b398SJiri Olsa 				   PERF_RECORD_SAMPLE, mctx->fp);
20384bd1bef8SAndi Kleen 	fputs("\tmetric: ", mctx->fp);
20394bd1bef8SAndi Kleen 	if (color)
20404bd1bef8SAndi Kleen 		color_fprintf(mctx->fp, color, fmt, val);
20414bd1bef8SAndi Kleen 	else
20424bd1bef8SAndi Kleen 		printf(fmt, val);
20434bd1bef8SAndi Kleen 	fprintf(mctx->fp, " %s\n", unit);
20444bd1bef8SAndi Kleen }
20454bd1bef8SAndi Kleen 
script_new_line(struct perf_stat_config * config __maybe_unused,void * ctx)20466ca9a082SJiri Olsa static void script_new_line(struct perf_stat_config *config __maybe_unused,
20476ca9a082SJiri Olsa 			    void *ctx)
20484bd1bef8SAndi Kleen {
20494bd1bef8SAndi Kleen 	struct metric_ctx *mctx = ctx;
20504bd1bef8SAndi Kleen 
2051e534bfb1SJiri Olsa 	perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
205228a0b398SJiri Olsa 				   PERF_RECORD_SAMPLE, mctx->fp);
20534bd1bef8SAndi Kleen 	fputs("\tmetric: ", mctx->fp);
20544bd1bef8SAndi Kleen }
20554bd1bef8SAndi Kleen 
perf_sample__fprint_metric(struct perf_script * script,struct thread * thread,struct evsel * evsel,struct perf_sample * sample,FILE * fp)20564bd1bef8SAndi Kleen static void perf_sample__fprint_metric(struct perf_script *script,
20574bd1bef8SAndi Kleen 				       struct thread *thread,
205832dcd021SJiri Olsa 				       struct evsel *evsel,
20594bd1bef8SAndi Kleen 				       struct perf_sample *sample,
20604bd1bef8SAndi Kleen 				       FILE *fp)
20614bd1bef8SAndi Kleen {
2062fba7c866SJiri Olsa 	struct evsel *leader = evsel__leader(evsel);
20634bd1bef8SAndi Kleen 	struct perf_stat_output_ctx ctx = {
20644bd1bef8SAndi Kleen 		.print_metric = script_print_metric,
20654bd1bef8SAndi Kleen 		.new_line = script_new_line,
20664bd1bef8SAndi Kleen 		.ctx = &(struct metric_ctx) {
20674bd1bef8SAndi Kleen 				.sample = sample,
20684bd1bef8SAndi Kleen 				.thread = thread,
20694bd1bef8SAndi Kleen 				.evsel  = evsel,
20704bd1bef8SAndi Kleen 				.fp     = fp,
20714bd1bef8SAndi Kleen 			 },
20724bd1bef8SAndi Kleen 		.force_header = false,
20734bd1bef8SAndi Kleen 	};
207432dcd021SJiri Olsa 	struct evsel *ev2;
20754bd1bef8SAndi Kleen 	u64 val;
20764bd1bef8SAndi Kleen 
20774bd1bef8SAndi Kleen 	if (!evsel->stats)
20781f297a6eSNamhyung Kim 		evlist__alloc_stats(&stat_config, script->session->evlist, /*alloc_raw=*/false);
2079fba7c866SJiri Olsa 	if (evsel_script(leader)->gnum++ == 0)
20804bd1bef8SAndi Kleen 		perf_stat__reset_shadow_stats();
20814bd1bef8SAndi Kleen 	val = sample->period * evsel->scale;
20824bd1bef8SAndi Kleen 	evsel_script(evsel)->val = val;
2083fba7c866SJiri Olsa 	if (evsel_script(leader)->gnum == leader->core.nr_members) {
2084fba7c866SJiri Olsa 		for_each_group_member (ev2, leader) {
20856ca9a082SJiri Olsa 			perf_stat__print_shadow_stats(&stat_config, ev2,
20864bd1bef8SAndi Kleen 						      evsel_script(ev2)->val,
20874bd1bef8SAndi Kleen 						      sample->cpu,
20884bd1bef8SAndi Kleen 						      &ctx,
2089cc26ffaaSIan Rogers 						      NULL);
20904bd1bef8SAndi Kleen 		}
2091fba7c866SJiri Olsa 		evsel_script(leader)->gnum = 0;
20924bd1bef8SAndi Kleen 	}
20934bd1bef8SAndi Kleen }
20944bd1bef8SAndi Kleen 
show_event(struct perf_sample * sample,struct evsel * evsel,struct thread * thread,struct addr_location * al,struct addr_location * addr_al)209599f753f0SAndi Kleen static bool show_event(struct perf_sample *sample,
209632dcd021SJiri Olsa 		       struct evsel *evsel,
209799f753f0SAndi Kleen 		       struct thread *thread,
2098b743b86cSAdrian Hunter 		       struct addr_location *al,
2099b743b86cSAdrian Hunter 		       struct addr_location *addr_al)
210099f753f0SAndi Kleen {
2101256d92bcSAdrian Hunter 	int depth = thread_stack__depth(thread, sample->cpu);
210299f753f0SAndi Kleen 
210399f753f0SAndi Kleen 	if (!symbol_conf.graph_function)
210499f753f0SAndi Kleen 		return true;
210599f753f0SAndi Kleen 
2106ee84a303SIan Rogers 	if (thread__filter(thread)) {
2107ee84a303SIan Rogers 		if (depth <= thread__filter_entry_depth(thread)) {
2108ee84a303SIan Rogers 			thread__set_filter(thread, false);
210999f753f0SAndi Kleen 			return false;
211099f753f0SAndi Kleen 		}
211199f753f0SAndi Kleen 		return true;
211299f753f0SAndi Kleen 	} else {
211399f753f0SAndi Kleen 		const char *s = symbol_conf.graph_function;
211499f753f0SAndi Kleen 		u64 ip;
2115b743b86cSAdrian Hunter 		const char *name = resolve_branch_sym(sample, evsel, thread, al, addr_al,
211699f753f0SAndi Kleen 				&ip);
211799f753f0SAndi Kleen 		unsigned nlen;
211899f753f0SAndi Kleen 
211999f753f0SAndi Kleen 		if (!name)
212099f753f0SAndi Kleen 			return false;
212199f753f0SAndi Kleen 		nlen = strlen(name);
212299f753f0SAndi Kleen 		while (*s) {
212399f753f0SAndi Kleen 			unsigned len = strcspn(s, ",");
212499f753f0SAndi Kleen 			if (nlen == len && !strncmp(name, s, len)) {
2125ee84a303SIan Rogers 				thread__set_filter(thread, true);
2126ee84a303SIan Rogers 				thread__set_filter_entry_depth(thread, depth);
212799f753f0SAndi Kleen 				return true;
212899f753f0SAndi Kleen 			}
212999f753f0SAndi Kleen 			s += len;
213099f753f0SAndi Kleen 			if (*s == ',')
213199f753f0SAndi Kleen 				s++;
213299f753f0SAndi Kleen 		}
213399f753f0SAndi Kleen 		return false;
213499f753f0SAndi Kleen 	}
213599f753f0SAndi Kleen }
213699f753f0SAndi Kleen 
process_event(struct perf_script * script,struct perf_sample * sample,struct evsel * evsel,struct addr_location * al,struct addr_location * addr_al,struct machine * machine)2137a3dff304SArnaldo Carvalho de Melo static void process_event(struct perf_script *script,
213832dcd021SJiri Olsa 			  struct perf_sample *sample, struct evsel *evsel,
213948d02a1dSAndi Kleen 			  struct addr_location *al,
2140b743b86cSAdrian Hunter 			  struct addr_location *addr_al,
214148d02a1dSAndi Kleen 			  struct machine *machine)
2142be6d842aSDavid Ahern {
2143f9d5d549SArnaldo Carvalho de Melo 	struct thread *thread = al->thread;
21441fc632ceSJiri Olsa 	struct perf_event_attr *attr = &evsel->core.attr;
21451405720dSAdrian Hunter 	unsigned int type = output_type(attr->type);
214632dcd021SJiri Olsa 	struct evsel_script *es = evsel->priv;
2147642ee1c6SArnaldo Carvalho de Melo 	FILE *fp = es->fp;
21486b9bae63SKan Liang 	char str[PAGE_SIZE_NAME_LEN];
214983869019SGerman Gomez 	const char *arch = perf_env__arch(machine->env);
21501424dc96SDavid Ahern 
21511405720dSAdrian Hunter 	if (output[type].fields == 0)
21521424dc96SDavid Ahern 		return;
21531424dc96SDavid Ahern 
2154642ee1c6SArnaldo Carvalho de Melo 	++es->samples;
2155642ee1c6SArnaldo Carvalho de Melo 
2156e534bfb1SJiri Olsa 	perf_sample__fprintf_start(script, sample, thread, evsel,
215728a0b398SJiri Olsa 				   PERF_RECORD_SAMPLE, fp);
2158745f43e3SDavid Ahern 
2159535aeaaeSJiri Olsa 	if (PRINT_FIELD(PERIOD))
216069c71252SArnaldo Carvalho de Melo 		fprintf(fp, "%10" PRIu64 " ", sample->period);
2161535aeaaeSJiri Olsa 
2162e944d3d7SNamhyung Kim 	if (PRINT_FIELD(EVNAME)) {
21638ab2e96dSArnaldo Carvalho de Melo 		const char *evname = evsel__name(evsel);
21649cdbc409SJiri Olsa 
21659cdbc409SJiri Olsa 		if (!script->name_width)
2166afdd63f5SArnaldo Carvalho de Melo 			script->name_width = evlist__max_name_len(script->session->evlist);
21679cdbc409SJiri Olsa 
216869c71252SArnaldo Carvalho de Melo 		fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]");
2169e944d3d7SNamhyung Kim 	}
2170e944d3d7SNamhyung Kim 
2171400ea6d3SAdrian Hunter 	if (print_flags)
2172a1a58707SArnaldo Carvalho de Melo 		perf_sample__fprintf_flags(sample->flags, fp);
2173400ea6d3SAdrian Hunter 
217495582596SAkihiro Nagai 	if (is_bts_event(attr)) {
2175b743b86cSAdrian Hunter 		perf_sample__fprintf_bts(sample, evsel, thread, al, addr_al, machine, fp);
217695582596SAkihiro Nagai 		return;
217795582596SAkihiro Nagai 	}
2178378ef0f5SIan Rogers #ifdef HAVE_LIBTRACEEVENT
217996167167SAndi Kleen 	if (PRINT_FIELD(TRACE) && sample->raw_data) {
2180894f3f17SArnaldo Carvalho de Melo 		event_format__fprintf(evsel->tp_format, sample->cpu,
2181894f3f17SArnaldo Carvalho de Melo 				      sample->raw_data, sample->raw_size, fp);
2182894f3f17SArnaldo Carvalho de Melo 	}
2183378ef0f5SIan Rogers #endif
218447e78084SAdrian Hunter 	if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
2185a1a58707SArnaldo Carvalho de Melo 		perf_sample__fprintf_synth(sample, evsel, fp);
218647e78084SAdrian Hunter 
21877cec0922SDavid Ahern 	if (PRINT_FIELD(ADDR))
2188a1a58707SArnaldo Carvalho de Melo 		perf_sample__fprintf_addr(sample, thread, attr, fp);
21897cec0922SDavid Ahern 
219094ddddfaSJiri Olsa 	if (PRINT_FIELD(DATA_SRC))
2191a1a58707SArnaldo Carvalho de Melo 		data_src__fprintf(sample->data_src, fp);
219294ddddfaSJiri Olsa 
219394ddddfaSJiri Olsa 	if (PRINT_FIELD(WEIGHT))
2194a1a58707SArnaldo Carvalho de Melo 		fprintf(fp, "%16" PRIu64, sample->weight);
219594ddddfaSJiri Olsa 
21966ea5d1a3SKan Liang 	if (PRINT_FIELD(INS_LAT))
21976ea5d1a3SKan Liang 		fprintf(fp, "%16" PRIu16, sample->ins_lat);
21986ea5d1a3SKan Liang 
219917f248aaSKan Liang 	if (PRINT_FIELD(RETIRE_LAT))
220017f248aaSKan Liang 		fprintf(fp, "%16" PRIu16, sample->retire_lat);
220117f248aaSKan Liang 
22028c49c6e1SIvan Babrou 	if (PRINT_FIELD(CGROUP)) {
22038c49c6e1SIvan Babrou 		const char *cgrp_name;
22048c49c6e1SIvan Babrou 		struct cgroup *cgrp = cgroup__find(machine->env,
22058c49c6e1SIvan Babrou 						   sample->cgroup);
22068c49c6e1SIvan Babrou 		if (cgrp != NULL)
22078c49c6e1SIvan Babrou 			cgrp_name = cgrp->name;
22088c49c6e1SIvan Babrou 		else
22098c49c6e1SIvan Babrou 			cgrp_name = "unknown";
22108c49c6e1SIvan Babrou 		fprintf(fp, " %s", cgrp_name);
22118c49c6e1SIvan Babrou 	}
22128c49c6e1SIvan Babrou 
2213787bef17SDavid Ahern 	if (PRINT_FIELD(IP)) {
2214e557b674SChris Phlipot 		struct callchain_cursor *cursor = NULL;
2215a6ffaf91SDavid Ahern 
2216680d125cSKan Liang 		if (script->stitch_lbr)
2217ee84a303SIan Rogers 			thread__set_lbr_stitch_enable(al->thread, true);
2218680d125cSKan Liang 
22198ab12a20SIan Rogers 		if (symbol_conf.use_callchain && sample->callchain) {
22208ab12a20SIan Rogers 			cursor = get_tls_callchain_cursor();
22218ab12a20SIan Rogers 			if (thread__resolve_callchain(al->thread, cursor, evsel,
22228ab12a20SIan Rogers 						      sample, NULL, NULL,
22238ab12a20SIan Rogers 						      scripting_max_stack))
22248ab12a20SIan Rogers 				cursor = NULL;
22258ab12a20SIan Rogers 		}
2226a1a58707SArnaldo Carvalho de Melo 		fputc(cursor ? '\n' : ' ', fp);
22279620bc36SArnaldo Carvalho de Melo 		sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor,
22289620bc36SArnaldo Carvalho de Melo 				    symbol_conf.bt_stop_list, fp);
2229c0230b2bSDavid Ahern 	}
2230c0230b2bSDavid Ahern 
2231fc36f948SStephane Eranian 	if (PRINT_FIELD(IREGS))
223283869019SGerman Gomez 		perf_sample__fprintf_iregs(sample, attr, arch, fp);
2233fc36f948SStephane Eranian 
2234b1491aceSAndi Kleen 	if (PRINT_FIELD(UREGS))
223583869019SGerman Gomez 		perf_sample__fprintf_uregs(sample, attr, arch, fp);
2236b1491aceSAndi Kleen 
2237dc323ce8SStephane Eranian 	if (PRINT_FIELD(BRSTACK))
2238a1a58707SArnaldo Carvalho de Melo 		perf_sample__fprintf_brstack(sample, thread, attr, fp);
2239dc323ce8SStephane Eranian 	else if (PRINT_FIELD(BRSTACKSYM))
2240a1a58707SArnaldo Carvalho de Melo 		perf_sample__fprintf_brstacksym(sample, thread, attr, fp);
2241106dacd8SMark Santaniello 	else if (PRINT_FIELD(BRSTACKOFF))
2242a1a58707SArnaldo Carvalho de Melo 		perf_sample__fprintf_brstackoff(sample, thread, attr, fp);
2243dc323ce8SStephane Eranian 
2244c754c382SArnaldo Carvalho de Melo 	if (evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
2245a1a58707SArnaldo Carvalho de Melo 		perf_sample__fprintf_bpf_output(sample, fp);
2246a1a58707SArnaldo Carvalho de Melo 	perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
224749d58f04SKan Liang 
224849d58f04SKan Liang 	if (PRINT_FIELD(PHYS_ADDR))
224969c71252SArnaldo Carvalho de Melo 		fprintf(fp, "%16" PRIx64, sample->phys_addr);
225068fb45bfSAdrian Hunter 
22516b9bae63SKan Liang 	if (PRINT_FIELD(DATA_PAGE_SIZE))
22526b9bae63SKan Liang 		fprintf(fp, " %s", get_page_size_name(sample->data_page_size, str));
22536b9bae63SKan Liang 
2254c513de8aSStephane Eranian 	if (PRINT_FIELD(CODE_PAGE_SIZE))
2255c513de8aSStephane Eranian 		fprintf(fp, " %s", get_page_size_name(sample->code_page_size, str));
2256c513de8aSStephane Eranian 
225768fb45bfSAdrian Hunter 	perf_sample__fprintf_ipc(sample, attr, fp);
225868fb45bfSAdrian Hunter 
225969c71252SArnaldo Carvalho de Melo 	fprintf(fp, "\n");
22604bd1bef8SAndi Kleen 
2261dd2e18e9SAndi Kleen 	if (PRINT_FIELD(SRCCODE)) {
2262dd2e18e9SAndi Kleen 		if (map__fprintf_srccode(al->map, al->addr, stdout,
2263ee84a303SIan Rogers 					 thread__srccode_state(thread)))
2264dd2e18e9SAndi Kleen 			printf("\n");
2265dd2e18e9SAndi Kleen 	}
2266dd2e18e9SAndi Kleen 
22674bd1bef8SAndi Kleen 	if (PRINT_FIELD(METRIC))
22684bd1bef8SAndi Kleen 		perf_sample__fprint_metric(script, thread, evsel, sample, fp);
22697ee40678SMilian Wolff 
22707c0a6144SYang Jihong 	if (verbose > 0)
22717ee40678SMilian Wolff 		fflush(fp);
2272be6d842aSDavid Ahern }
2273be6d842aSDavid Ahern 
2274133dc4c3SIngo Molnar static struct scripting_ops	*scripting_ops;
2275133dc4c3SIngo Molnar 
__process_stat(struct evsel * counter,u64 tstamp)227632dcd021SJiri Olsa static void __process_stat(struct evsel *counter, u64 tstamp)
227736e33c53SJiri Olsa {
2278a2f354e3SJiri Olsa 	int nthreads = perf_thread_map__nr(counter->core.threads);
22796d18804bSIan Rogers 	int idx, thread;
22806d18804bSIan Rogers 	struct perf_cpu cpu;
228136e33c53SJiri Olsa 	static int header_printed;
228236e33c53SJiri Olsa 
228336e33c53SJiri Olsa 	if (!header_printed) {
228436e33c53SJiri Olsa 		printf("%3s %8s %15s %15s %15s %15s %s\n",
228536e33c53SJiri Olsa 		       "CPU", "THREAD", "VAL", "ENA", "RUN", "TIME", "EVENT");
228636e33c53SJiri Olsa 		header_printed = 1;
228736e33c53SJiri Olsa 	}
228836e33c53SJiri Olsa 
228936e33c53SJiri Olsa 	for (thread = 0; thread < nthreads; thread++) {
2290f9551b3fSIan Rogers 		perf_cpu_map__for_each_cpu(cpu, idx, evsel__cpus(counter)) {
229136e33c53SJiri Olsa 			struct perf_counts_values *counts;
229236e33c53SJiri Olsa 
2293b57af1b4SIan Rogers 			counts = perf_counts(counter->counts, idx, thread);
229436e33c53SJiri Olsa 
229536e33c53SJiri Olsa 			printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n",
22966d18804bSIan Rogers 				cpu.cpu,
2297a2f354e3SJiri Olsa 				perf_thread_map__pid(counter->core.threads, thread),
229836e33c53SJiri Olsa 				counts->val,
229936e33c53SJiri Olsa 				counts->ena,
230036e33c53SJiri Olsa 				counts->run,
230136e33c53SJiri Olsa 				tstamp,
23028ab2e96dSArnaldo Carvalho de Melo 				evsel__name(counter));
230336e33c53SJiri Olsa 		}
230436e33c53SJiri Olsa 	}
230536e33c53SJiri Olsa }
230636e33c53SJiri Olsa 
process_stat(struct evsel * counter,u64 tstamp)230732dcd021SJiri Olsa static void process_stat(struct evsel *counter, u64 tstamp)
2308e099eba8SJiri Olsa {
2309e099eba8SJiri Olsa 	if (scripting_ops && scripting_ops->process_stat)
2310e099eba8SJiri Olsa 		scripting_ops->process_stat(&stat_config, counter, tstamp);
231136e33c53SJiri Olsa 	else
231236e33c53SJiri Olsa 		__process_stat(counter, tstamp);
2313e099eba8SJiri Olsa }
2314e099eba8SJiri Olsa 
process_stat_interval(u64 tstamp)2315e099eba8SJiri Olsa static void process_stat_interval(u64 tstamp)
2316e099eba8SJiri Olsa {
2317e099eba8SJiri Olsa 	if (scripting_ops && scripting_ops->process_stat_interval)
2318e099eba8SJiri Olsa 		scripting_ops->process_stat_interval(tstamp);
2319e099eba8SJiri Olsa }
2320e099eba8SJiri Olsa 
setup_scripting(void)2321133dc4c3SIngo Molnar static void setup_scripting(void)
2322133dc4c3SIngo Molnar {
2323378ef0f5SIan Rogers #ifdef HAVE_LIBTRACEEVENT
2324133dc4c3SIngo Molnar 	setup_perl_scripting();
2325378ef0f5SIan Rogers #endif
232680c3a7d9SAdrian Hunter 	setup_python_scripting();
2327133dc4c3SIngo Molnar }
2328133dc4c3SIngo Molnar 
flush_scripting(void)2329d445dd2aSAdrian Hunter static int flush_scripting(void)
2330d445dd2aSAdrian Hunter {
23312aaecfc5SJiri Olsa 	return scripting_ops ? scripting_ops->flush_script() : 0;
2332d445dd2aSAdrian Hunter }
2333d445dd2aSAdrian Hunter 
cleanup_scripting(void)2334133dc4c3SIngo Molnar static int cleanup_scripting(void)
2335133dc4c3SIngo Molnar {
2336133dc4c3SIngo Molnar 	pr_debug("\nperf script stopped\n");
2337133dc4c3SIngo Molnar 
23382aaecfc5SJiri Olsa 	return scripting_ops ? scripting_ops->stop_script() : 0;
2339133dc4c3SIngo Molnar }
2340133dc4c3SIngo Molnar 
filter_cpu(struct perf_sample * sample)2341e87e5481SAndi Kleen static bool filter_cpu(struct perf_sample *sample)
2342e87e5481SAndi Kleen {
23431a2725f3SAdrian Hunter 	if (cpu_list && sample->cpu != (u32)-1)
2344e87e5481SAndi Kleen 		return !test_bit(sample->cpu, cpu_bitmap);
2345e87e5481SAndi Kleen 	return false;
2346e87e5481SAndi Kleen }
2347e87e5481SAndi Kleen 
process_sample_event(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct evsel * evsel,struct machine * machine)2348809e9423SJiri Olsa static int process_sample_event(struct perf_tool *tool,
2349d20deb64SArnaldo Carvalho de Melo 				union perf_event *event,
23508115d60cSArnaldo Carvalho de Melo 				struct perf_sample *sample,
235132dcd021SJiri Olsa 				struct evsel *evsel,
2352743eb868SArnaldo Carvalho de Melo 				struct machine *machine)
2353133dc4c3SIngo Molnar {
2354809e9423SJiri Olsa 	struct perf_script *scr = container_of(tool, struct perf_script, tool);
2355e7984b7bSDavid Ahern 	struct addr_location al;
2356b743b86cSAdrian Hunter 	struct addr_location addr_al;
2357291961fcSAdrian Hunter 	int ret = 0;
2358133dc4c3SIngo Molnar 
23599bde93a7SAdrian Hunter 	/* Set thread to NULL to indicate addr_al and al are not initialized */
23600dd5041cSIan Rogers 	addr_location__init(&al);
23610dd5041cSIan Rogers 	addr_location__init(&addr_al);
23629bde93a7SAdrian Hunter 
23639bde93a7SAdrian Hunter 	ret = dlfilter__filter_event_early(dlfilter, event, sample, evsel, machine, &al, &addr_al);
23649bde93a7SAdrian Hunter 	if (ret) {
23659bde93a7SAdrian Hunter 		if (ret > 0)
23669bde93a7SAdrian Hunter 			ret = 0;
23679bde93a7SAdrian Hunter 		goto out_put;
23689bde93a7SAdrian Hunter 	}
23699bde93a7SAdrian Hunter 
23702ab046cdSJin Yao 	if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num,
23712ab046cdSJin Yao 					  sample->time)) {
23729bde93a7SAdrian Hunter 		goto out_put;
23732ab046cdSJin Yao 	}
2374a91f4c47SDavid Ahern 
2375133dc4c3SIngo Molnar 	if (debug_mode) {
2376640c03ceSArnaldo Carvalho de Melo 		if (sample->time < last_timestamp) {
23779486aa38SArnaldo Carvalho de Melo 			pr_err("Samples misordered, previous: %" PRIu64
23789486aa38SArnaldo Carvalho de Melo 				" this: %" PRIu64 "\n", last_timestamp,
2379640c03ceSArnaldo Carvalho de Melo 				sample->time);
2380133dc4c3SIngo Molnar 			nr_unordered++;
2381133dc4c3SIngo Molnar 		}
2382640c03ceSArnaldo Carvalho de Melo 		last_timestamp = sample->time;
23839bde93a7SAdrian Hunter 		goto out_put;
2384133dc4c3SIngo Molnar 	}
23855d67be97SAnton Blanchard 
23869300041cSAdrian Hunter 	if (filter_cpu(sample))
23879bde93a7SAdrian Hunter 		goto out_put;
23889300041cSAdrian Hunter 
238929159727SAdrian Hunter 	if (!al.thread && machine__resolve(machine, &al, sample) < 0) {
2390e7984b7bSDavid Ahern 		pr_err("problem processing %d event, skipping it.\n",
2391e7984b7bSDavid Ahern 		       event->header.type);
23929bde93a7SAdrian Hunter 		ret = -1;
23939bde93a7SAdrian Hunter 		goto out_put;
2394e7984b7bSDavid Ahern 	}
2395e7984b7bSDavid Ahern 
2396e7984b7bSDavid Ahern 	if (al.filtered)
2397b91fc39fSArnaldo Carvalho de Melo 		goto out_put;
2398e7984b7bSDavid Ahern 
2399b743b86cSAdrian Hunter 	if (!show_event(sample, evsel, al.thread, &al, &addr_al))
24004371fbc0SAdrian Hunter 		goto out_put;
24014371fbc0SAdrian Hunter 
24024371fbc0SAdrian Hunter 	if (evswitch__discard(&scr->evswitch, evsel))
24034371fbc0SAdrian Hunter 		goto out_put;
24044371fbc0SAdrian Hunter 
2405291961fcSAdrian Hunter 	ret = dlfilter__filter_event(dlfilter, event, sample, evsel, machine, &al, &addr_al);
2406291961fcSAdrian Hunter 	if (ret) {
2407291961fcSAdrian Hunter 		if (ret > 0)
2408291961fcSAdrian Hunter 			ret = 0;
2409291961fcSAdrian Hunter 		goto out_put;
2410291961fcSAdrian Hunter 	}
2411291961fcSAdrian Hunter 
24123f8e009eSAdrian Hunter 	if (scripting_ops) {
24133f8e009eSAdrian Hunter 		struct addr_location *addr_al_ptr = NULL;
24143f8e009eSAdrian Hunter 
24153f8e009eSAdrian Hunter 		if ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
24163f8e009eSAdrian Hunter 		    sample_addr_correlates_sym(&evsel->core.attr)) {
2417b743b86cSAdrian Hunter 			if (!addr_al.thread)
24183f8e009eSAdrian Hunter 				thread__resolve(al.thread, &addr_al, sample);
24193f8e009eSAdrian Hunter 			addr_al_ptr = &addr_al;
24203f8e009eSAdrian Hunter 		}
24213f8e009eSAdrian Hunter 		scripting_ops->process_event(event, sample, evsel, &al, addr_al_ptr);
24223f8e009eSAdrian Hunter 	} else {
2423b743b86cSAdrian Hunter 		process_event(scr, sample, evsel, &al, &addr_al, machine);
24243f8e009eSAdrian Hunter 	}
24252aaecfc5SJiri Olsa 
2426b91fc39fSArnaldo Carvalho de Melo out_put:
24270dd5041cSIan Rogers 	addr_location__exit(&addr_al);
24280dd5041cSIan Rogers 	addr_location__exit(&al);
2429291961fcSAdrian Hunter 	return ret;
2430133dc4c3SIngo Molnar }
2431133dc4c3SIngo Molnar 
243236d3e413SArnaldo Carvalho de Melo // Used when scr->per_event_dump is not set
243336d3e413SArnaldo Carvalho de Melo static struct evsel_script es_stdout;
243436d3e413SArnaldo Carvalho de Melo 
process_attr(struct perf_tool * tool,union perf_event * event,struct evlist ** pevlist)24357ea95727SAdrian Hunter static int process_attr(struct perf_tool *tool, union perf_event *event,
243663503dbaSJiri Olsa 			struct evlist **pevlist)
24377ea95727SAdrian Hunter {
24387ea95727SAdrian Hunter 	struct perf_script *scr = container_of(tool, struct perf_script, tool);
243963503dbaSJiri Olsa 	struct evlist *evlist;
244032dcd021SJiri Olsa 	struct evsel *evsel, *pos;
24410d71a2b2SJiri Olsa 	u64 sample_type;
24427ea95727SAdrian Hunter 	int err;
24437ea95727SAdrian Hunter 
24447ea95727SAdrian Hunter 	err = perf_event__process_attr(tool, event, pevlist);
24457ea95727SAdrian Hunter 	if (err)
24467ea95727SAdrian Hunter 		return err;
24477ea95727SAdrian Hunter 
24487ea95727SAdrian Hunter 	evlist = *pevlist;
2449515dbe48SJiri Olsa 	evsel = evlist__last(*pevlist);
24507ea95727SAdrian Hunter 
2451a3af66f5SRavi Bangoria 	if (!evsel->priv) {
2452a3af66f5SRavi Bangoria 		if (scr->per_event_dump) {
2453297e69bfSArnaldo Carvalho de Melo 			evsel->priv = evsel_script__new(evsel, scr->session->data);
245436d3e413SArnaldo Carvalho de Melo 			if (!evsel->priv)
2455a3af66f5SRavi Bangoria 				return -ENOMEM;
245636d3e413SArnaldo Carvalho de Melo 		} else { // Replicate what is done in perf_script__setup_per_event_dump()
245736d3e413SArnaldo Carvalho de Melo 			es_stdout.fp = stdout;
245836d3e413SArnaldo Carvalho de Melo 			evsel->priv = &es_stdout;
2459a3af66f5SRavi Bangoria 		}
2460a3af66f5SRavi Bangoria 	}
2461a3af66f5SRavi Bangoria 
24621fc632ceSJiri Olsa 	if (evsel->core.attr.type >= PERF_TYPE_MAX &&
24631fc632ceSJiri Olsa 	    evsel->core.attr.type != PERF_TYPE_SYNTH)
24647ea95727SAdrian Hunter 		return 0;
24657ea95727SAdrian Hunter 
2466e5cadb93SArnaldo Carvalho de Melo 	evlist__for_each_entry(evlist, pos) {
24671fc632ceSJiri Olsa 		if (pos->core.attr.type == evsel->core.attr.type && pos != evsel)
24687ea95727SAdrian Hunter 			return 0;
24697ea95727SAdrian Hunter 	}
24707ea95727SAdrian Hunter 
24710d71a2b2SJiri Olsa 	if (evsel->core.attr.sample_type) {
2472afdd63f5SArnaldo Carvalho de Melo 		err = evsel__check_attr(evsel, scr->session);
24730d71a2b2SJiri Olsa 		if (err)
2474d2b5a315SJiri Olsa 			return err;
24757ea95727SAdrian Hunter 	}
24767ea95727SAdrian Hunter 
24770d71a2b2SJiri Olsa 	/*
24780d71a2b2SJiri Olsa 	 * Check if we need to enable callchains based
24790d71a2b2SJiri Olsa 	 * on events sample_type.
24800d71a2b2SJiri Olsa 	 */
2481b3c2cc2bSArnaldo Carvalho de Melo 	sample_type = evlist__combined_sample_type(evlist);
2482aa8db3e4SAlexandre Truong 	callchain_param_setup(sample_type, perf_env__arch((*pevlist)->env));
248353fb1894SJiri Olsa 
2484b5164085SAdrian Hunter 	/* Enable fields for callchain entries */
2485b5164085SAdrian Hunter 	if (symbol_conf.use_callchain &&
2486b5164085SAdrian Hunter 	    (sample_type & PERF_SAMPLE_CALLCHAIN ||
2487b5164085SAdrian Hunter 	     sample_type & PERF_SAMPLE_BRANCH_STACK ||
2488b5164085SAdrian Hunter 	     (sample_type & PERF_SAMPLE_REGS_USER &&
2489b5164085SAdrian Hunter 	      sample_type & PERF_SAMPLE_STACK_USER))) {
2490b5164085SAdrian Hunter 		int type = output_type(evsel->core.attr.type);
2491b5164085SAdrian Hunter 
2492b5164085SAdrian Hunter 		if (!(output[type].user_unset_fields & PERF_OUTPUT_IP))
2493b5164085SAdrian Hunter 			output[type].fields |= PERF_OUTPUT_IP;
2494b5164085SAdrian Hunter 		if (!(output[type].user_unset_fields & PERF_OUTPUT_SYM))
2495b5164085SAdrian Hunter 			output[type].fields |= PERF_OUTPUT_SYM;
249653fb1894SJiri Olsa 	}
249753fb1894SJiri Olsa 	set_print_ip_opts(&evsel->core.attr);
24980d71a2b2SJiri Olsa 	return 0;
24990d71a2b2SJiri Olsa }
25000d71a2b2SJiri Olsa 
print_event_with_time(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine,pid_t pid,pid_t tid,u64 timestamp)25011a2725f3SAdrian Hunter static int print_event_with_time(struct perf_tool *tool,
25021a2725f3SAdrian Hunter 				 union perf_event *event,
25031a2725f3SAdrian Hunter 				 struct perf_sample *sample,
25041a2725f3SAdrian Hunter 				 struct machine *machine,
25051a2725f3SAdrian Hunter 				 pid_t pid, pid_t tid, u64 timestamp)
25061a2725f3SAdrian Hunter {
25071a2725f3SAdrian Hunter 	struct perf_script *script = container_of(tool, struct perf_script, tool);
25081a2725f3SAdrian Hunter 	struct perf_session *session = script->session;
25093ccf8a7bSArnaldo Carvalho de Melo 	struct evsel *evsel = evlist__id2evsel(session->evlist, sample->id);
25101a2725f3SAdrian Hunter 	struct thread *thread = NULL;
25111a2725f3SAdrian Hunter 
25121a2725f3SAdrian Hunter 	if (evsel && !evsel->core.attr.sample_id_all) {
25131a2725f3SAdrian Hunter 		sample->cpu = 0;
25141a2725f3SAdrian Hunter 		sample->time = timestamp;
25151a2725f3SAdrian Hunter 		sample->pid = pid;
25161a2725f3SAdrian Hunter 		sample->tid = tid;
25171a2725f3SAdrian Hunter 	}
25181a2725f3SAdrian Hunter 
25191a2725f3SAdrian Hunter 	if (filter_cpu(sample))
25201a2725f3SAdrian Hunter 		return 0;
25211a2725f3SAdrian Hunter 
25221a2725f3SAdrian Hunter 	if (tid != -1)
25231a2725f3SAdrian Hunter 		thread = machine__findnew_thread(machine, pid, tid);
25241a2725f3SAdrian Hunter 
2525fc18380fSAdrian Hunter 	if (evsel) {
2526e534bfb1SJiri Olsa 		perf_sample__fprintf_start(script, sample, thread, evsel,
25271a2725f3SAdrian Hunter 					   event->header.type, stdout);
25281a2725f3SAdrian Hunter 	}
25291a2725f3SAdrian Hunter 
25307eeb9855SAdrian Hunter 	perf_event__fprintf(event, machine, stdout);
25311a2725f3SAdrian Hunter 
25321a2725f3SAdrian Hunter 	thread__put(thread);
25331a2725f3SAdrian Hunter 
25341a2725f3SAdrian Hunter 	return 0;
25351a2725f3SAdrian Hunter }
25361a2725f3SAdrian Hunter 
print_event(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine,pid_t pid,pid_t tid)25371a2725f3SAdrian Hunter static int print_event(struct perf_tool *tool, union perf_event *event,
25381a2725f3SAdrian Hunter 		       struct perf_sample *sample, struct machine *machine,
25391a2725f3SAdrian Hunter 		       pid_t pid, pid_t tid)
25401a2725f3SAdrian Hunter {
25411a2725f3SAdrian Hunter 	return print_event_with_time(tool, event, sample, machine, pid, tid, 0);
25421a2725f3SAdrian Hunter }
25431a2725f3SAdrian Hunter 
process_comm_event(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine)2544ad7ebb9aSNamhyung Kim static int process_comm_event(struct perf_tool *tool,
2545ad7ebb9aSNamhyung Kim 			      union perf_event *event,
2546ad7ebb9aSNamhyung Kim 			      struct perf_sample *sample,
2547ad7ebb9aSNamhyung Kim 			      struct machine *machine)
2548ad7ebb9aSNamhyung Kim {
2549ad7ebb9aSNamhyung Kim 	if (perf_event__process_comm(tool, event, sample, machine) < 0)
25501a2725f3SAdrian Hunter 		return -1;
2551ad7ebb9aSNamhyung Kim 
25521a2725f3SAdrian Hunter 	return print_event(tool, event, sample, machine, event->comm.pid,
25531a2725f3SAdrian Hunter 			   event->comm.tid);
2554ad7ebb9aSNamhyung Kim }
2555ad7ebb9aSNamhyung Kim 
process_namespaces_event(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine)255696a44bbcSHari Bathini static int process_namespaces_event(struct perf_tool *tool,
255796a44bbcSHari Bathini 				    union perf_event *event,
255896a44bbcSHari Bathini 				    struct perf_sample *sample,
255996a44bbcSHari Bathini 				    struct machine *machine)
256096a44bbcSHari Bathini {
256196a44bbcSHari Bathini 	if (perf_event__process_namespaces(tool, event, sample, machine) < 0)
25621a2725f3SAdrian Hunter 		return -1;
256396a44bbcSHari Bathini 
25641a2725f3SAdrian Hunter 	return print_event(tool, event, sample, machine, event->namespaces.pid,
25651a2725f3SAdrian Hunter 			   event->namespaces.tid);
256696a44bbcSHari Bathini }
256796a44bbcSHari Bathini 
process_cgroup_event(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine)2568160d4af9SNamhyung Kim static int process_cgroup_event(struct perf_tool *tool,
2569160d4af9SNamhyung Kim 				union perf_event *event,
2570160d4af9SNamhyung Kim 				struct perf_sample *sample,
2571160d4af9SNamhyung Kim 				struct machine *machine)
2572160d4af9SNamhyung Kim {
2573160d4af9SNamhyung Kim 	if (perf_event__process_cgroup(tool, event, sample, machine) < 0)
25741a2725f3SAdrian Hunter 		return -1;
2575160d4af9SNamhyung Kim 
25761a2725f3SAdrian Hunter 	return print_event(tool, event, sample, machine, sample->pid,
25771a2725f3SAdrian Hunter 			    sample->tid);
2578160d4af9SNamhyung Kim }
2579160d4af9SNamhyung Kim 
process_fork_event(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine)2580ad7ebb9aSNamhyung Kim static int process_fork_event(struct perf_tool *tool,
2581ad7ebb9aSNamhyung Kim 			      union perf_event *event,
2582ad7ebb9aSNamhyung Kim 			      struct perf_sample *sample,
2583ad7ebb9aSNamhyung Kim 			      struct machine *machine)
2584ad7ebb9aSNamhyung Kim {
2585ad7ebb9aSNamhyung Kim 	if (perf_event__process_fork(tool, event, sample, machine) < 0)
2586ad7ebb9aSNamhyung Kim 		return -1;
2587ad7ebb9aSNamhyung Kim 
25881a2725f3SAdrian Hunter 	return print_event_with_time(tool, event, sample, machine,
25891a2725f3SAdrian Hunter 				     event->fork.pid, event->fork.tid,
25901a2725f3SAdrian Hunter 				     event->fork.time);
2591ad7ebb9aSNamhyung Kim }
process_exit_event(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine)2592ad7ebb9aSNamhyung Kim static int process_exit_event(struct perf_tool *tool,
2593ad7ebb9aSNamhyung Kim 			      union perf_event *event,
2594ad7ebb9aSNamhyung Kim 			      struct perf_sample *sample,
2595ad7ebb9aSNamhyung Kim 			      struct machine *machine)
2596ad7ebb9aSNamhyung Kim {
25971a2725f3SAdrian Hunter 	/* Print before 'exit' deletes anything */
25981a2725f3SAdrian Hunter 	if (print_event_with_time(tool, event, sample, machine, event->fork.pid,
25991a2725f3SAdrian Hunter 				  event->fork.tid, event->fork.time))
2600ad7ebb9aSNamhyung Kim 		return -1;
2601ad7ebb9aSNamhyung Kim 
26021a2725f3SAdrian Hunter 	return perf_event__process_exit(tool, event, sample, machine);
2603ad7ebb9aSNamhyung Kim }
2604ad7ebb9aSNamhyung Kim 
process_mmap_event(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine)2605ba1ddf42SNamhyung Kim static int process_mmap_event(struct perf_tool *tool,
2606ba1ddf42SNamhyung Kim 			      union perf_event *event,
2607ba1ddf42SNamhyung Kim 			      struct perf_sample *sample,
2608ba1ddf42SNamhyung Kim 			      struct machine *machine)
2609ba1ddf42SNamhyung Kim {
2610ba1ddf42SNamhyung Kim 	if (perf_event__process_mmap(tool, event, sample, machine) < 0)
2611ba1ddf42SNamhyung Kim 		return -1;
2612ba1ddf42SNamhyung Kim 
26131a2725f3SAdrian Hunter 	return print_event(tool, event, sample, machine, event->mmap.pid,
26141a2725f3SAdrian Hunter 			   event->mmap.tid);
2615ba1ddf42SNamhyung Kim }
2616ba1ddf42SNamhyung Kim 
process_mmap2_event(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine)2617ba1ddf42SNamhyung Kim static int process_mmap2_event(struct perf_tool *tool,
2618ba1ddf42SNamhyung Kim 			      union perf_event *event,
2619ba1ddf42SNamhyung Kim 			      struct perf_sample *sample,
2620ba1ddf42SNamhyung Kim 			      struct machine *machine)
2621ba1ddf42SNamhyung Kim {
2622ba1ddf42SNamhyung Kim 	if (perf_event__process_mmap2(tool, event, sample, machine) < 0)
2623ba1ddf42SNamhyung Kim 		return -1;
2624ba1ddf42SNamhyung Kim 
26251a2725f3SAdrian Hunter 	return print_event(tool, event, sample, machine, event->mmap2.pid,
26261a2725f3SAdrian Hunter 			   event->mmap2.tid);
2627ba1ddf42SNamhyung Kim }
2628ba1ddf42SNamhyung Kim 
process_switch_event(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine)26297c14898bSAdrian Hunter static int process_switch_event(struct perf_tool *tool,
26307c14898bSAdrian Hunter 				union perf_event *event,
26317c14898bSAdrian Hunter 				struct perf_sample *sample,
26327c14898bSAdrian Hunter 				struct machine *machine)
26337c14898bSAdrian Hunter {
26347c14898bSAdrian Hunter 	struct perf_script *script = container_of(tool, struct perf_script, tool);
26357c14898bSAdrian Hunter 
26367c14898bSAdrian Hunter 	if (perf_event__process_switch(tool, event, sample, machine) < 0)
26377c14898bSAdrian Hunter 		return -1;
26387c14898bSAdrian Hunter 
26395e0c325cSAdrian Hunter 	if (scripting_ops && scripting_ops->process_switch && !filter_cpu(sample))
26405bf83c29SAdrian Hunter 		scripting_ops->process_switch(event, sample, machine);
26415bf83c29SAdrian Hunter 
26425bf83c29SAdrian Hunter 	if (!script->show_switch_events)
26435bf83c29SAdrian Hunter 		return 0;
26445bf83c29SAdrian Hunter 
26451a2725f3SAdrian Hunter 	return print_event(tool, event, sample, machine, sample->pid,
26467c14898bSAdrian Hunter 			   sample->tid);
26477c14898bSAdrian Hunter }
26487c14898bSAdrian Hunter 
process_auxtrace_error(struct perf_session * session,union perf_event * event)26492ede9217SAdrian Hunter static int process_auxtrace_error(struct perf_session *session,
26502ede9217SAdrian Hunter 				  union perf_event *event)
26512ede9217SAdrian Hunter {
26522ede9217SAdrian Hunter 	if (scripting_ops && scripting_ops->process_auxtrace_error) {
26532ede9217SAdrian Hunter 		scripting_ops->process_auxtrace_error(session, event);
26542ede9217SAdrian Hunter 		return 0;
26552ede9217SAdrian Hunter 	}
26562ede9217SAdrian Hunter 
26572ede9217SAdrian Hunter 	return perf_event__process_auxtrace_error(session, event);
26582ede9217SAdrian Hunter }
26592ede9217SAdrian Hunter 
26603d7c27b6SJiri Olsa static int
process_lost_event(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine)26613d7c27b6SJiri Olsa process_lost_event(struct perf_tool *tool,
26623d7c27b6SJiri Olsa 		   union perf_event *event,
26633d7c27b6SJiri Olsa 		   struct perf_sample *sample,
26643d7c27b6SJiri Olsa 		   struct machine *machine)
26653d7c27b6SJiri Olsa {
26661a2725f3SAdrian Hunter 	return print_event(tool, event, sample, machine, sample->pid,
26673d7c27b6SJiri Olsa 			   sample->tid);
26683d7c27b6SJiri Olsa }
26693d7c27b6SJiri Olsa 
26703233b37aSJiri Olsa static int
process_throttle_event(struct perf_tool * tool __maybe_unused,union perf_event * event,struct perf_sample * sample,struct machine * machine)2671538d9c18SStephen Brennan process_throttle_event(struct perf_tool *tool __maybe_unused,
2672538d9c18SStephen Brennan 		       union perf_event *event,
2673538d9c18SStephen Brennan 		       struct perf_sample *sample,
2674538d9c18SStephen Brennan 		       struct machine *machine)
2675538d9c18SStephen Brennan {
2676538d9c18SStephen Brennan 	if (scripting_ops && scripting_ops->process_throttle)
2677538d9c18SStephen Brennan 		scripting_ops->process_throttle(event, sample, machine);
2678538d9c18SStephen Brennan 	return 0;
2679538d9c18SStephen Brennan }
2680538d9c18SStephen Brennan 
2681538d9c18SStephen Brennan static int
process_finished_round_event(struct perf_tool * tool __maybe_unused,union perf_event * event,struct ordered_events * oe __maybe_unused)26823233b37aSJiri Olsa process_finished_round_event(struct perf_tool *tool __maybe_unused,
26833233b37aSJiri Olsa 			     union perf_event *event,
26843233b37aSJiri Olsa 			     struct ordered_events *oe __maybe_unused)
26853233b37aSJiri Olsa 
26863233b37aSJiri Olsa {
26877eeb9855SAdrian Hunter 	perf_event__fprintf(event, NULL, stdout);
26883233b37aSJiri Olsa 	return 0;
26893233b37aSJiri Olsa }
26903233b37aSJiri Olsa 
2691490c8cc9SJiri Olsa static int
process_bpf_events(struct perf_tool * tool __maybe_unused,union perf_event * event,struct perf_sample * sample,struct machine * machine)2692490c8cc9SJiri Olsa process_bpf_events(struct perf_tool *tool __maybe_unused,
2693490c8cc9SJiri Olsa 		   union perf_event *event,
2694490c8cc9SJiri Olsa 		   struct perf_sample *sample,
2695490c8cc9SJiri Olsa 		   struct machine *machine)
2696490c8cc9SJiri Olsa {
2697490c8cc9SJiri Olsa 	if (machine__process_ksymbol(machine, event, sample) < 0)
2698490c8cc9SJiri Olsa 		return -1;
2699490c8cc9SJiri Olsa 
27001a2725f3SAdrian Hunter 	return print_event(tool, event, sample, machine, sample->pid,
27011a2725f3SAdrian Hunter 			   sample->tid);
2702490c8cc9SJiri Olsa }
2703490c8cc9SJiri Olsa 
process_text_poke_events(struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine)270492ecf3a6SAdrian Hunter static int process_text_poke_events(struct perf_tool *tool,
270592ecf3a6SAdrian Hunter 				    union perf_event *event,
270692ecf3a6SAdrian Hunter 				    struct perf_sample *sample,
270792ecf3a6SAdrian Hunter 				    struct machine *machine)
270892ecf3a6SAdrian Hunter {
270992ecf3a6SAdrian Hunter 	if (perf_event__process_text_poke(tool, event, sample, machine) < 0)
271092ecf3a6SAdrian Hunter 		return -1;
271192ecf3a6SAdrian Hunter 
271292ecf3a6SAdrian Hunter 	return print_event(tool, event, sample, machine, sample->pid,
271392ecf3a6SAdrian Hunter 			   sample->tid);
271492ecf3a6SAdrian Hunter }
271592ecf3a6SAdrian Hunter 
sig_handler(int sig __maybe_unused)27161d037ca1SIrina Tirdea static void sig_handler(int sig __maybe_unused)
2717133dc4c3SIngo Molnar {
2718133dc4c3SIngo Molnar 	session_done = 1;
2719133dc4c3SIngo Molnar }
2720133dc4c3SIngo Molnar 
perf_script__fclose_per_event_dump(struct perf_script * script)2721a14390fdSArnaldo Carvalho de Melo static void perf_script__fclose_per_event_dump(struct perf_script *script)
2722a14390fdSArnaldo Carvalho de Melo {
272363503dbaSJiri Olsa 	struct evlist *evlist = script->session->evlist;
272432dcd021SJiri Olsa 	struct evsel *evsel;
2725a14390fdSArnaldo Carvalho de Melo 
2726a14390fdSArnaldo Carvalho de Melo 	evlist__for_each_entry(evlist, evsel) {
2727a14390fdSArnaldo Carvalho de Melo 		if (!evsel->priv)
2728a14390fdSArnaldo Carvalho de Melo 			break;
2729297e69bfSArnaldo Carvalho de Melo 		evsel_script__delete(evsel->priv);
2730a14390fdSArnaldo Carvalho de Melo 		evsel->priv = NULL;
2731a14390fdSArnaldo Carvalho de Melo 	}
2732a14390fdSArnaldo Carvalho de Melo }
2733a14390fdSArnaldo Carvalho de Melo 
perf_script__fopen_per_event_dump(struct perf_script * script)2734a14390fdSArnaldo Carvalho de Melo static int perf_script__fopen_per_event_dump(struct perf_script *script)
2735a14390fdSArnaldo Carvalho de Melo {
273632dcd021SJiri Olsa 	struct evsel *evsel;
2737a14390fdSArnaldo Carvalho de Melo 
2738a14390fdSArnaldo Carvalho de Melo 	evlist__for_each_entry(script->session->evlist, evsel) {
2739fa48c892SArnaldo Carvalho de Melo 		/*
2740fa48c892SArnaldo Carvalho de Melo 		 * Already setup? I.e. we may be called twice in cases like
2741fa48c892SArnaldo Carvalho de Melo 		 * Intel PT, one for the intel_pt// and dummy events, then
27424d39c89fSIngo Molnar 		 * for the evsels synthesized from the auxtrace info.
2743fa48c892SArnaldo Carvalho de Melo 		 *
2744fa48c892SArnaldo Carvalho de Melo 		 * Ses perf_script__process_auxtrace_info.
2745fa48c892SArnaldo Carvalho de Melo 		 */
2746fa48c892SArnaldo Carvalho de Melo 		if (evsel->priv != NULL)
2747fa48c892SArnaldo Carvalho de Melo 			continue;
2748fa48c892SArnaldo Carvalho de Melo 
2749297e69bfSArnaldo Carvalho de Melo 		evsel->priv = evsel_script__new(evsel, script->session->data);
2750a14390fdSArnaldo Carvalho de Melo 		if (evsel->priv == NULL)
2751a14390fdSArnaldo Carvalho de Melo 			goto out_err_fclose;
2752a14390fdSArnaldo Carvalho de Melo 	}
2753a14390fdSArnaldo Carvalho de Melo 
2754a14390fdSArnaldo Carvalho de Melo 	return 0;
2755a14390fdSArnaldo Carvalho de Melo 
2756a14390fdSArnaldo Carvalho de Melo out_err_fclose:
2757a14390fdSArnaldo Carvalho de Melo 	perf_script__fclose_per_event_dump(script);
2758a14390fdSArnaldo Carvalho de Melo 	return -1;
2759a14390fdSArnaldo Carvalho de Melo }
2760a14390fdSArnaldo Carvalho de Melo 
perf_script__setup_per_event_dump(struct perf_script * script)2761a14390fdSArnaldo Carvalho de Melo static int perf_script__setup_per_event_dump(struct perf_script *script)
2762a14390fdSArnaldo Carvalho de Melo {
276332dcd021SJiri Olsa 	struct evsel *evsel;
2764a14390fdSArnaldo Carvalho de Melo 
2765a14390fdSArnaldo Carvalho de Melo 	if (script->per_event_dump)
2766a14390fdSArnaldo Carvalho de Melo 		return perf_script__fopen_per_event_dump(script);
2767a14390fdSArnaldo Carvalho de Melo 
2768642ee1c6SArnaldo Carvalho de Melo 	es_stdout.fp = stdout;
2769642ee1c6SArnaldo Carvalho de Melo 
2770a14390fdSArnaldo Carvalho de Melo 	evlist__for_each_entry(script->session->evlist, evsel)
2771642ee1c6SArnaldo Carvalho de Melo 		evsel->priv = &es_stdout;
2772a14390fdSArnaldo Carvalho de Melo 
2773a14390fdSArnaldo Carvalho de Melo 	return 0;
2774a14390fdSArnaldo Carvalho de Melo }
2775a14390fdSArnaldo Carvalho de Melo 
perf_script__exit_per_event_dump_stats(struct perf_script * script)2776642ee1c6SArnaldo Carvalho de Melo static void perf_script__exit_per_event_dump_stats(struct perf_script *script)
2777642ee1c6SArnaldo Carvalho de Melo {
277832dcd021SJiri Olsa 	struct evsel *evsel;
2779642ee1c6SArnaldo Carvalho de Melo 
2780642ee1c6SArnaldo Carvalho de Melo 	evlist__for_each_entry(script->session->evlist, evsel) {
278132dcd021SJiri Olsa 		struct evsel_script *es = evsel->priv;
2782642ee1c6SArnaldo Carvalho de Melo 
2783297e69bfSArnaldo Carvalho de Melo 		evsel_script__fprintf(es, stdout);
2784297e69bfSArnaldo Carvalho de Melo 		evsel_script__delete(es);
2785642ee1c6SArnaldo Carvalho de Melo 		evsel->priv = NULL;
2786642ee1c6SArnaldo Carvalho de Melo 	}
2787642ee1c6SArnaldo Carvalho de Melo }
2788642ee1c6SArnaldo Carvalho de Melo 
perf_script__exit(struct perf_script * script)2789faf3ac30SRiccardo Mancini static void perf_script__exit(struct perf_script *script)
2790faf3ac30SRiccardo Mancini {
2791faf3ac30SRiccardo Mancini 	perf_thread_map__put(script->threads);
2792faf3ac30SRiccardo Mancini 	perf_cpu_map__put(script->cpus);
2793faf3ac30SRiccardo Mancini }
2794faf3ac30SRiccardo Mancini 
__cmd_script(struct perf_script * script)27956f3e5edaSAdrian Hunter static int __cmd_script(struct perf_script *script)
2796133dc4c3SIngo Molnar {
2797133dc4c3SIngo Molnar 	int ret;
2798133dc4c3SIngo Molnar 
2799133dc4c3SIngo Molnar 	signal(SIGINT, sig_handler);
2800133dc4c3SIngo Molnar 
2801ad7ebb9aSNamhyung Kim 	/* override event processing functions */
2802ad7ebb9aSNamhyung Kim 	if (script->show_task_events) {
2803ad7ebb9aSNamhyung Kim 		script->tool.comm = process_comm_event;
2804ad7ebb9aSNamhyung Kim 		script->tool.fork = process_fork_event;
2805ad7ebb9aSNamhyung Kim 		script->tool.exit = process_exit_event;
2806ad7ebb9aSNamhyung Kim 	}
2807ba1ddf42SNamhyung Kim 	if (script->show_mmap_events) {
2808ba1ddf42SNamhyung Kim 		script->tool.mmap = process_mmap_event;
2809ba1ddf42SNamhyung Kim 		script->tool.mmap2 = process_mmap2_event;
2810ba1ddf42SNamhyung Kim 	}
28115bf83c29SAdrian Hunter 	if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch))
28127c14898bSAdrian Hunter 		script->tool.context_switch = process_switch_event;
28132ede9217SAdrian Hunter 	if (scripting_ops && scripting_ops->process_auxtrace_error)
28142ede9217SAdrian Hunter 		script->tool.auxtrace_error = process_auxtrace_error;
281596a44bbcSHari Bathini 	if (script->show_namespace_events)
281696a44bbcSHari Bathini 		script->tool.namespaces = process_namespaces_event;
2817160d4af9SNamhyung Kim 	if (script->show_cgroup_events)
2818160d4af9SNamhyung Kim 		script->tool.cgroup = process_cgroup_event;
28193d7c27b6SJiri Olsa 	if (script->show_lost_events)
28203d7c27b6SJiri Olsa 		script->tool.lost = process_lost_event;
28213233b37aSJiri Olsa 	if (script->show_round_events) {
28223233b37aSJiri Olsa 		script->tool.ordered_events = false;
28233233b37aSJiri Olsa 		script->tool.finished_round = process_finished_round_event;
28243233b37aSJiri Olsa 	}
2825490c8cc9SJiri Olsa 	if (script->show_bpf_events) {
2826490c8cc9SJiri Olsa 		script->tool.ksymbol = process_bpf_events;
28273f604b5fSArnaldo Carvalho de Melo 		script->tool.bpf     = process_bpf_events;
2828490c8cc9SJiri Olsa 	}
282992ecf3a6SAdrian Hunter 	if (script->show_text_poke_events) {
283092ecf3a6SAdrian Hunter 		script->tool.ksymbol   = process_bpf_events;
283192ecf3a6SAdrian Hunter 		script->tool.text_poke = process_text_poke_events;
283292ecf3a6SAdrian Hunter 	}
2833ad7ebb9aSNamhyung Kim 
2834a14390fdSArnaldo Carvalho de Melo 	if (perf_script__setup_per_event_dump(script)) {
2835a14390fdSArnaldo Carvalho de Melo 		pr_err("Couldn't create the per event dump files\n");
2836a14390fdSArnaldo Carvalho de Melo 		return -1;
2837a14390fdSArnaldo Carvalho de Melo 	}
2838a14390fdSArnaldo Carvalho de Melo 
2839b7b61cbeSArnaldo Carvalho de Melo 	ret = perf_session__process_events(script->session);
2840133dc4c3SIngo Molnar 
2841a14390fdSArnaldo Carvalho de Melo 	if (script->per_event_dump)
2842642ee1c6SArnaldo Carvalho de Melo 		perf_script__exit_per_event_dump_stats(script);
2843a14390fdSArnaldo Carvalho de Melo 
28446d8afb56SArnaldo Carvalho de Melo 	if (debug_mode)
28459486aa38SArnaldo Carvalho de Melo 		pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
2846133dc4c3SIngo Molnar 
2847133dc4c3SIngo Molnar 	return ret;
2848133dc4c3SIngo Molnar }
2849133dc4c3SIngo Molnar 
2850133dc4c3SIngo Molnar struct script_spec {
2851133dc4c3SIngo Molnar 	struct list_head	node;
2852133dc4c3SIngo Molnar 	struct scripting_ops	*ops;
28536549a8c0SGustavo A. R. Silva 	char			spec[];
2854133dc4c3SIngo Molnar };
2855133dc4c3SIngo Molnar 
2856eccdfe2dSArnaldo Carvalho de Melo static LIST_HEAD(script_specs);
2857133dc4c3SIngo Molnar 
script_spec__new(const char * spec,struct scripting_ops * ops)2858133dc4c3SIngo Molnar static struct script_spec *script_spec__new(const char *spec,
2859133dc4c3SIngo Molnar 					    struct scripting_ops *ops)
2860133dc4c3SIngo Molnar {
2861133dc4c3SIngo Molnar 	struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
2862133dc4c3SIngo Molnar 
2863133dc4c3SIngo Molnar 	if (s != NULL) {
2864133dc4c3SIngo Molnar 		strcpy(s->spec, spec);
2865133dc4c3SIngo Molnar 		s->ops = ops;
2866133dc4c3SIngo Molnar 	}
2867133dc4c3SIngo Molnar 
2868133dc4c3SIngo Molnar 	return s;
2869133dc4c3SIngo Molnar }
2870133dc4c3SIngo Molnar 
script_spec__add(struct script_spec * s)2871133dc4c3SIngo Molnar static void script_spec__add(struct script_spec *s)
2872133dc4c3SIngo Molnar {
2873133dc4c3SIngo Molnar 	list_add_tail(&s->node, &script_specs);
2874133dc4c3SIngo Molnar }
2875133dc4c3SIngo Molnar 
script_spec__find(const char * spec)2876133dc4c3SIngo Molnar static struct script_spec *script_spec__find(const char *spec)
2877133dc4c3SIngo Molnar {
2878133dc4c3SIngo Molnar 	struct script_spec *s;
2879133dc4c3SIngo Molnar 
2880133dc4c3SIngo Molnar 	list_for_each_entry(s, &script_specs, node)
2881133dc4c3SIngo Molnar 		if (strcasecmp(s->spec, spec) == 0)
2882133dc4c3SIngo Molnar 			return s;
2883133dc4c3SIngo Molnar 	return NULL;
2884133dc4c3SIngo Molnar }
2885133dc4c3SIngo Molnar 
script_spec_register(const char * spec,struct scripting_ops * ops)2886133dc4c3SIngo Molnar int script_spec_register(const char *spec, struct scripting_ops *ops)
2887133dc4c3SIngo Molnar {
2888133dc4c3SIngo Molnar 	struct script_spec *s;
2889133dc4c3SIngo Molnar 
2890133dc4c3SIngo Molnar 	s = script_spec__find(spec);
2891133dc4c3SIngo Molnar 	if (s)
2892133dc4c3SIngo Molnar 		return -1;
2893133dc4c3SIngo Molnar 
28948560bae0STaeung Song 	s = script_spec__new(spec, ops);
2895133dc4c3SIngo Molnar 	if (!s)
2896133dc4c3SIngo Molnar 		return -1;
28978560bae0STaeung Song 	else
28988560bae0STaeung Song 		script_spec__add(s);
2899133dc4c3SIngo Molnar 
2900133dc4c3SIngo Molnar 	return 0;
2901133dc4c3SIngo Molnar }
2902133dc4c3SIngo Molnar 
script_spec__lookup(const char * spec)2903133dc4c3SIngo Molnar static struct scripting_ops *script_spec__lookup(const char *spec)
2904133dc4c3SIngo Molnar {
2905133dc4c3SIngo Molnar 	struct script_spec *s = script_spec__find(spec);
2906133dc4c3SIngo Molnar 	if (!s)
2907133dc4c3SIngo Molnar 		return NULL;
2908133dc4c3SIngo Molnar 
2909133dc4c3SIngo Molnar 	return s->ops;
2910133dc4c3SIngo Molnar }
2911133dc4c3SIngo Molnar 
list_available_languages(void)2912133dc4c3SIngo Molnar static void list_available_languages(void)
2913133dc4c3SIngo Molnar {
2914133dc4c3SIngo Molnar 	struct script_spec *s;
2915133dc4c3SIngo Molnar 
2916133dc4c3SIngo Molnar 	fprintf(stderr, "\n");
2917133dc4c3SIngo Molnar 	fprintf(stderr, "Scripting language extensions (used in "
2918133dc4c3SIngo Molnar 		"perf script -s [spec:]script.[spec]):\n\n");
2919133dc4c3SIngo Molnar 
2920133dc4c3SIngo Molnar 	list_for_each_entry(s, &script_specs, node)
2921133dc4c3SIngo Molnar 		fprintf(stderr, "  %-42s [%s]\n", s->spec, s->ops->name);
2922133dc4c3SIngo Molnar 
2923133dc4c3SIngo Molnar 	fprintf(stderr, "\n");
2924133dc4c3SIngo Molnar }
2925133dc4c3SIngo Molnar 
29266ea4b5dbSAdrian Hunter /* Find script file relative to current directory or exec path */
find_script(const char * script)29276ea4b5dbSAdrian Hunter static char *find_script(const char *script)
29286ea4b5dbSAdrian Hunter {
29296ea4b5dbSAdrian Hunter 	char path[PATH_MAX];
29306ea4b5dbSAdrian Hunter 
29316ea4b5dbSAdrian Hunter 	if (!scripting_ops) {
29326ea4b5dbSAdrian Hunter 		const char *ext = strrchr(script, '.');
29336ea4b5dbSAdrian Hunter 
29346ea4b5dbSAdrian Hunter 		if (!ext)
29356ea4b5dbSAdrian Hunter 			return NULL;
29366ea4b5dbSAdrian Hunter 
29376ea4b5dbSAdrian Hunter 		scripting_ops = script_spec__lookup(++ext);
29386ea4b5dbSAdrian Hunter 		if (!scripting_ops)
29396ea4b5dbSAdrian Hunter 			return NULL;
29406ea4b5dbSAdrian Hunter 	}
29416ea4b5dbSAdrian Hunter 
29426ea4b5dbSAdrian Hunter 	if (access(script, R_OK)) {
29436ea4b5dbSAdrian Hunter 		char *exec_path = get_argv_exec_path();
29446ea4b5dbSAdrian Hunter 
29456ea4b5dbSAdrian Hunter 		if (!exec_path)
29466ea4b5dbSAdrian Hunter 			return NULL;
29476ea4b5dbSAdrian Hunter 		snprintf(path, sizeof(path), "%s/scripts/%s/%s",
29486ea4b5dbSAdrian Hunter 			 exec_path, scripting_ops->dirname, script);
29496ea4b5dbSAdrian Hunter 		free(exec_path);
29506ea4b5dbSAdrian Hunter 		script = path;
29516ea4b5dbSAdrian Hunter 		if (access(script, R_OK))
29526ea4b5dbSAdrian Hunter 			return NULL;
29536ea4b5dbSAdrian Hunter 	}
29546ea4b5dbSAdrian Hunter 	return strdup(script);
29556ea4b5dbSAdrian Hunter }
29566ea4b5dbSAdrian Hunter 
parse_scriptname(const struct option * opt __maybe_unused,const char * str,int unset __maybe_unused)29571d037ca1SIrina Tirdea static int parse_scriptname(const struct option *opt __maybe_unused,
29581d037ca1SIrina Tirdea 			    const char *str, int unset __maybe_unused)
2959133dc4c3SIngo Molnar {
2960133dc4c3SIngo Molnar 	char spec[PATH_MAX];
2961133dc4c3SIngo Molnar 	const char *script, *ext;
2962133dc4c3SIngo Molnar 	int len;
2963133dc4c3SIngo Molnar 
2964133dc4c3SIngo Molnar 	if (strcmp(str, "lang") == 0) {
2965133dc4c3SIngo Molnar 		list_available_languages();
2966133dc4c3SIngo Molnar 		exit(0);
2967133dc4c3SIngo Molnar 	}
2968133dc4c3SIngo Molnar 
2969133dc4c3SIngo Molnar 	script = strchr(str, ':');
2970133dc4c3SIngo Molnar 	if (script) {
2971133dc4c3SIngo Molnar 		len = script - str;
2972133dc4c3SIngo Molnar 		if (len >= PATH_MAX) {
2973133dc4c3SIngo Molnar 			fprintf(stderr, "invalid language specifier");
2974133dc4c3SIngo Molnar 			return -1;
2975133dc4c3SIngo Molnar 		}
2976133dc4c3SIngo Molnar 		strncpy(spec, str, len);
2977133dc4c3SIngo Molnar 		spec[len] = '\0';
2978133dc4c3SIngo Molnar 		scripting_ops = script_spec__lookup(spec);
2979133dc4c3SIngo Molnar 		if (!scripting_ops) {
2980133dc4c3SIngo Molnar 			fprintf(stderr, "invalid language specifier");
2981133dc4c3SIngo Molnar 			return -1;
2982133dc4c3SIngo Molnar 		}
2983133dc4c3SIngo Molnar 		script++;
2984133dc4c3SIngo Molnar 	} else {
2985133dc4c3SIngo Molnar 		script = str;
2986133dc4c3SIngo Molnar 		ext = strrchr(script, '.');
2987133dc4c3SIngo Molnar 		if (!ext) {
2988133dc4c3SIngo Molnar 			fprintf(stderr, "invalid script extension");
2989133dc4c3SIngo Molnar 			return -1;
2990133dc4c3SIngo Molnar 		}
2991133dc4c3SIngo Molnar 		scripting_ops = script_spec__lookup(++ext);
2992133dc4c3SIngo Molnar 		if (!scripting_ops) {
2993133dc4c3SIngo Molnar 			fprintf(stderr, "invalid script extension");
2994133dc4c3SIngo Molnar 			return -1;
2995133dc4c3SIngo Molnar 		}
2996133dc4c3SIngo Molnar 	}
2997133dc4c3SIngo Molnar 
29986ea4b5dbSAdrian Hunter 	script_name = find_script(script);
29996ea4b5dbSAdrian Hunter 	if (!script_name)
3000133dc4c3SIngo Molnar 		script_name = strdup(script);
3001133dc4c3SIngo Molnar 
3002133dc4c3SIngo Molnar 	return 0;
3003133dc4c3SIngo Molnar }
3004133dc4c3SIngo Molnar 
parse_output_fields(const struct option * opt __maybe_unused,const char * arg,int unset __maybe_unused)30051d037ca1SIrina Tirdea static int parse_output_fields(const struct option *opt __maybe_unused,
30061d037ca1SIrina Tirdea 			    const char *arg, int unset __maybe_unused)
3007745f43e3SDavid Ahern {
300849346e85SArnaldo Carvalho de Melo 	char *tok, *strtok_saveptr = NULL;
300950ca19aeSSasha Levin 	int i, imax = ARRAY_SIZE(all_output_options);
30102c9e45f7SDavid Ahern 	int j;
3011745f43e3SDavid Ahern 	int rc = 0;
3012745f43e3SDavid Ahern 	char *str = strdup(arg);
30131424dc96SDavid Ahern 	int type = -1;
301436ce5651SAndi Kleen 	enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;
3015745f43e3SDavid Ahern 
3016745f43e3SDavid Ahern 	if (!str)
3017745f43e3SDavid Ahern 		return -ENOMEM;
3018745f43e3SDavid Ahern 
30192c9e45f7SDavid Ahern 	/* first word can state for which event type the user is specifying
30202c9e45f7SDavid Ahern 	 * the fields. If no type exists, the specified fields apply to all
30212c9e45f7SDavid Ahern 	 * event types found in the file minus the invalid fields for a type.
30221424dc96SDavid Ahern 	 */
30232c9e45f7SDavid Ahern 	tok = strchr(str, ':');
30242c9e45f7SDavid Ahern 	if (tok) {
30252c9e45f7SDavid Ahern 		*tok = '\0';
30262c9e45f7SDavid Ahern 		tok++;
30272c9e45f7SDavid Ahern 		if (!strcmp(str, "hw"))
30281424dc96SDavid Ahern 			type = PERF_TYPE_HARDWARE;
30292c9e45f7SDavid Ahern 		else if (!strcmp(str, "sw"))
30301424dc96SDavid Ahern 			type = PERF_TYPE_SOFTWARE;
30312c9e45f7SDavid Ahern 		else if (!strcmp(str, "trace"))
30321424dc96SDavid Ahern 			type = PERF_TYPE_TRACEPOINT;
30330817a6a3SArun Sharma 		else if (!strcmp(str, "raw"))
30340817a6a3SArun Sharma 			type = PERF_TYPE_RAW;
303527cfef00SWang Nan 		else if (!strcmp(str, "break"))
303627cfef00SWang Nan 			type = PERF_TYPE_BREAKPOINT;
30371405720dSAdrian Hunter 		else if (!strcmp(str, "synth"))
30381405720dSAdrian Hunter 			type = OUTPUT_TYPE_SYNTH;
30391424dc96SDavid Ahern 		else {
30402c9e45f7SDavid Ahern 			fprintf(stderr, "Invalid event type in field string.\n");
304138efb539SRobert Richter 			rc = -EINVAL;
304238efb539SRobert Richter 			goto out;
30431424dc96SDavid Ahern 		}
30441424dc96SDavid Ahern 
30452c9e45f7SDavid Ahern 		if (output[type].user_set)
30462c9e45f7SDavid Ahern 			pr_warning("Overriding previous field request for %s events.\n",
30472c9e45f7SDavid Ahern 				   event_type(type));
30482c9e45f7SDavid Ahern 
30496ef362fdSJiri Olsa 		/* Don't override defaults for +- */
30506ef362fdSJiri Olsa 		if (strchr(tok, '+') || strchr(tok, '-'))
30516ef362fdSJiri Olsa 			goto parse;
30526ef362fdSJiri Olsa 
30532c9e45f7SDavid Ahern 		output[type].fields = 0;
30542c9e45f7SDavid Ahern 		output[type].user_set = true;
30559cbdb702SDavid Ahern 		output[type].wildcard_set = false;
30562c9e45f7SDavid Ahern 
30572c9e45f7SDavid Ahern 	} else {
30582c9e45f7SDavid Ahern 		tok = str;
30592c9e45f7SDavid Ahern 		if (strlen(str) == 0) {
30602c9e45f7SDavid Ahern 			fprintf(stderr,
30612c9e45f7SDavid Ahern 				"Cannot set fields to 'none' for all event types.\n");
30622c9e45f7SDavid Ahern 			rc = -EINVAL;
30632c9e45f7SDavid Ahern 			goto out;
3064745f43e3SDavid Ahern 		}
30652c9e45f7SDavid Ahern 
306636ce5651SAndi Kleen 		/* Don't override defaults for +- */
306736ce5651SAndi Kleen 		if (strchr(str, '+') || strchr(str, '-'))
306836ce5651SAndi Kleen 			goto parse;
306936ce5651SAndi Kleen 
30702c9e45f7SDavid Ahern 		if (output_set_by_user())
30712c9e45f7SDavid Ahern 			pr_warning("Overriding previous field request for all events.\n");
30722c9e45f7SDavid Ahern 
30731405720dSAdrian Hunter 		for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
30742c9e45f7SDavid Ahern 			output[j].fields = 0;
30752c9e45f7SDavid Ahern 			output[j].user_set = true;
30769cbdb702SDavid Ahern 			output[j].wildcard_set = true;
30772c9e45f7SDavid Ahern 		}
30782c9e45f7SDavid Ahern 	}
30792c9e45f7SDavid Ahern 
308036ce5651SAndi Kleen parse:
308149346e85SArnaldo Carvalho de Melo 	for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
308236ce5651SAndi Kleen 		if (*tok == '+') {
308336ce5651SAndi Kleen 			if (change == SET)
308436ce5651SAndi Kleen 				goto out_badmix;
308536ce5651SAndi Kleen 			change = ADD;
308636ce5651SAndi Kleen 			tok++;
308736ce5651SAndi Kleen 		} else if (*tok == '-') {
308836ce5651SAndi Kleen 			if (change == SET)
308936ce5651SAndi Kleen 				goto out_badmix;
309036ce5651SAndi Kleen 			change = REMOVE;
309136ce5651SAndi Kleen 			tok++;
309236ce5651SAndi Kleen 		} else {
309336ce5651SAndi Kleen 			if (change != SET && change != DEFAULT)
309436ce5651SAndi Kleen 				goto out_badmix;
309536ce5651SAndi Kleen 			change = SET;
309636ce5651SAndi Kleen 		}
309736ce5651SAndi Kleen 
30982c9e45f7SDavid Ahern 		for (i = 0; i < imax; ++i) {
30992c9e45f7SDavid Ahern 			if (strcmp(tok, all_output_options[i].str) == 0)
31002c9e45f7SDavid Ahern 				break;
3101745f43e3SDavid Ahern 		}
3102400ea6d3SAdrian Hunter 		if (i == imax && strcmp(tok, "flags") == 0) {
31038524711dSYang Li 			print_flags = change != REMOVE;
3104400ea6d3SAdrian Hunter 			continue;
3105400ea6d3SAdrian Hunter 		}
3106745f43e3SDavid Ahern 		if (i == imax) {
31072c9e45f7SDavid Ahern 			fprintf(stderr, "Invalid field requested.\n");
3108745f43e3SDavid Ahern 			rc = -EINVAL;
31092c9e45f7SDavid Ahern 			goto out;
31101424dc96SDavid Ahern 		}
3111745f43e3SDavid Ahern 
31122c9e45f7SDavid Ahern 		if (type == -1) {
31132c9e45f7SDavid Ahern 			/* add user option to all events types for
31142c9e45f7SDavid Ahern 			 * which it is valid
31152c9e45f7SDavid Ahern 			 */
31161405720dSAdrian Hunter 			for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
31172c9e45f7SDavid Ahern 				if (output[j].invalid_fields & all_output_options[i].field) {
31182c9e45f7SDavid Ahern 					pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
31192c9e45f7SDavid Ahern 						   all_output_options[i].str, event_type(j));
312036ce5651SAndi Kleen 				} else {
31214b6ac811SAndi Kleen 					if (change == REMOVE) {
312236ce5651SAndi Kleen 						output[j].fields &= ~all_output_options[i].field;
31234b6ac811SAndi Kleen 						output[j].user_set_fields &= ~all_output_options[i].field;
3124b5164085SAdrian Hunter 						output[j].user_unset_fields |= all_output_options[i].field;
31254b6ac811SAndi Kleen 					} else {
31262c9e45f7SDavid Ahern 						output[j].fields |= all_output_options[i].field;
31274b6ac811SAndi Kleen 						output[j].user_set_fields |= all_output_options[i].field;
3128b5164085SAdrian Hunter 						output[j].user_unset_fields &= ~all_output_options[i].field;
31294b6ac811SAndi Kleen 					}
313037fed3deSAndi Kleen 					output[j].user_set = true;
313137fed3deSAndi Kleen 					output[j].wildcard_set = true;
31322c9e45f7SDavid Ahern 				}
313336ce5651SAndi Kleen 			}
31342c9e45f7SDavid Ahern 		} else {
31352c9e45f7SDavid Ahern 			if (output[type].invalid_fields & all_output_options[i].field) {
31362c9e45f7SDavid Ahern 				fprintf(stderr, "\'%s\' not valid for %s events.\n",
31372c9e45f7SDavid Ahern 					 all_output_options[i].str, event_type(type));
31382c9e45f7SDavid Ahern 
31392c9e45f7SDavid Ahern 				rc = -EINVAL;
31402c9e45f7SDavid Ahern 				goto out;
31412c9e45f7SDavid Ahern 			}
31426ef362fdSJiri Olsa 			if (change == REMOVE)
31436ef362fdSJiri Olsa 				output[type].fields &= ~all_output_options[i].field;
31446ef362fdSJiri Olsa 			else
31456ef362fdSJiri Olsa 				output[type].fields |= all_output_options[i].field;
314637fed3deSAndi Kleen 			output[type].user_set = true;
314737fed3deSAndi Kleen 			output[type].wildcard_set = true;
31482c9e45f7SDavid Ahern 		}
31492c9e45f7SDavid Ahern 	}
31502c9e45f7SDavid Ahern 
31512c9e45f7SDavid Ahern 	if (type >= 0) {
31522c9e45f7SDavid Ahern 		if (output[type].fields == 0) {
31531424dc96SDavid Ahern 			pr_debug("No fields requested for %s type. "
31542c9e45f7SDavid Ahern 				 "Events will not be displayed.\n", event_type(type));
31552c9e45f7SDavid Ahern 		}
3156745f43e3SDavid Ahern 	}
315736ce5651SAndi Kleen 	goto out;
3158745f43e3SDavid Ahern 
315936ce5651SAndi Kleen out_badmix:
316036ce5651SAndi Kleen 	fprintf(stderr, "Cannot mix +-field with overridden fields\n");
316136ce5651SAndi Kleen 	rc = -EINVAL;
31622c9e45f7SDavid Ahern out:
3163745f43e3SDavid Ahern 	free(str);
3164745f43e3SDavid Ahern 	return rc;
3165745f43e3SDavid Ahern }
3166745f43e3SDavid Ahern 
3167a5e8e825SArnaldo Carvalho de Melo #define for_each_lang(scripts_path, scripts_dir, lang_dirent)		\
3168a5e8e825SArnaldo Carvalho de Melo 	while ((lang_dirent = readdir(scripts_dir)) != NULL)		\
3169a5e8e825SArnaldo Carvalho de Melo 		if ((lang_dirent->d_type == DT_DIR ||			\
3170a5e8e825SArnaldo Carvalho de Melo 		     (lang_dirent->d_type == DT_UNKNOWN &&		\
3171a5e8e825SArnaldo Carvalho de Melo 		      is_directory(scripts_path, lang_dirent))) &&	\
3172a5e8e825SArnaldo Carvalho de Melo 		    (strcmp(lang_dirent->d_name, ".")) &&		\
3173a5e8e825SArnaldo Carvalho de Melo 		    (strcmp(lang_dirent->d_name, "..")))
3174133dc4c3SIngo Molnar 
3175a5e8e825SArnaldo Carvalho de Melo #define for_each_script(lang_path, lang_dir, script_dirent)		\
3176a5e8e825SArnaldo Carvalho de Melo 	while ((script_dirent = readdir(lang_dir)) != NULL)		\
3177a5e8e825SArnaldo Carvalho de Melo 		if (script_dirent->d_type != DT_DIR &&			\
3178a5e8e825SArnaldo Carvalho de Melo 		    (script_dirent->d_type != DT_UNKNOWN ||		\
3179a5e8e825SArnaldo Carvalho de Melo 		     !is_directory(lang_path, script_dirent)))
3180133dc4c3SIngo Molnar 
3181133dc4c3SIngo Molnar 
3182133dc4c3SIngo Molnar #define RECORD_SUFFIX			"-record"
3183133dc4c3SIngo Molnar #define REPORT_SUFFIX			"-report"
3184133dc4c3SIngo Molnar 
3185133dc4c3SIngo Molnar struct script_desc {
3186133dc4c3SIngo Molnar 	struct list_head	node;
3187133dc4c3SIngo Molnar 	char			*name;
3188133dc4c3SIngo Molnar 	char			*half_liner;
3189133dc4c3SIngo Molnar 	char			*args;
3190133dc4c3SIngo Molnar };
3191133dc4c3SIngo Molnar 
3192eccdfe2dSArnaldo Carvalho de Melo static LIST_HEAD(script_descs);
3193133dc4c3SIngo Molnar 
script_desc__new(const char * name)3194133dc4c3SIngo Molnar static struct script_desc *script_desc__new(const char *name)
3195133dc4c3SIngo Molnar {
3196133dc4c3SIngo Molnar 	struct script_desc *s = zalloc(sizeof(*s));
3197133dc4c3SIngo Molnar 
3198133dc4c3SIngo Molnar 	if (s != NULL && name)
3199133dc4c3SIngo Molnar 		s->name = strdup(name);
3200133dc4c3SIngo Molnar 
3201133dc4c3SIngo Molnar 	return s;
3202133dc4c3SIngo Molnar }
3203133dc4c3SIngo Molnar 
script_desc__delete(struct script_desc * s)3204133dc4c3SIngo Molnar static void script_desc__delete(struct script_desc *s)
3205133dc4c3SIngo Molnar {
320674cf249dSArnaldo Carvalho de Melo 	zfree(&s->name);
320774cf249dSArnaldo Carvalho de Melo 	zfree(&s->half_liner);
320874cf249dSArnaldo Carvalho de Melo 	zfree(&s->args);
3209133dc4c3SIngo Molnar 	free(s);
3210133dc4c3SIngo Molnar }
3211133dc4c3SIngo Molnar 
script_desc__add(struct script_desc * s)3212133dc4c3SIngo Molnar static void script_desc__add(struct script_desc *s)
3213133dc4c3SIngo Molnar {
3214133dc4c3SIngo Molnar 	list_add_tail(&s->node, &script_descs);
3215133dc4c3SIngo Molnar }
3216133dc4c3SIngo Molnar 
script_desc__find(const char * name)3217133dc4c3SIngo Molnar static struct script_desc *script_desc__find(const char *name)
3218133dc4c3SIngo Molnar {
3219133dc4c3SIngo Molnar 	struct script_desc *s;
3220133dc4c3SIngo Molnar 
3221133dc4c3SIngo Molnar 	list_for_each_entry(s, &script_descs, node)
3222133dc4c3SIngo Molnar 		if (strcasecmp(s->name, name) == 0)
3223133dc4c3SIngo Molnar 			return s;
3224133dc4c3SIngo Molnar 	return NULL;
3225133dc4c3SIngo Molnar }
3226133dc4c3SIngo Molnar 
script_desc__findnew(const char * name)3227133dc4c3SIngo Molnar static struct script_desc *script_desc__findnew(const char *name)
3228133dc4c3SIngo Molnar {
3229133dc4c3SIngo Molnar 	struct script_desc *s = script_desc__find(name);
3230133dc4c3SIngo Molnar 
3231133dc4c3SIngo Molnar 	if (s)
3232133dc4c3SIngo Molnar 		return s;
3233133dc4c3SIngo Molnar 
3234133dc4c3SIngo Molnar 	s = script_desc__new(name);
3235133dc4c3SIngo Molnar 	if (!s)
32362ec5cab6SDan Carpenter 		return NULL;
3237133dc4c3SIngo Molnar 
3238133dc4c3SIngo Molnar 	script_desc__add(s);
3239133dc4c3SIngo Molnar 
3240133dc4c3SIngo Molnar 	return s;
3241133dc4c3SIngo Molnar }
3242133dc4c3SIngo Molnar 
ends_with(const char * str,const char * suffix)3243965bb6beSStephane Eranian static const char *ends_with(const char *str, const char *suffix)
3244133dc4c3SIngo Molnar {
3245133dc4c3SIngo Molnar 	size_t suffix_len = strlen(suffix);
3246965bb6beSStephane Eranian 	const char *p = str;
3247133dc4c3SIngo Molnar 
3248133dc4c3SIngo Molnar 	if (strlen(str) > suffix_len) {
3249133dc4c3SIngo Molnar 		p = str + strlen(str) - suffix_len;
3250133dc4c3SIngo Molnar 		if (!strncmp(p, suffix, suffix_len))
3251133dc4c3SIngo Molnar 			return p;
3252133dc4c3SIngo Molnar 	}
3253133dc4c3SIngo Molnar 
3254133dc4c3SIngo Molnar 	return NULL;
3255133dc4c3SIngo Molnar }
3256133dc4c3SIngo Molnar 
read_script_info(struct script_desc * desc,const char * filename)3257133dc4c3SIngo Molnar static int read_script_info(struct script_desc *desc, const char *filename)
3258133dc4c3SIngo Molnar {
3259133dc4c3SIngo Molnar 	char line[BUFSIZ], *p;
3260133dc4c3SIngo Molnar 	FILE *fp;
3261133dc4c3SIngo Molnar 
3262133dc4c3SIngo Molnar 	fp = fopen(filename, "r");
3263133dc4c3SIngo Molnar 	if (!fp)
3264133dc4c3SIngo Molnar 		return -1;
3265133dc4c3SIngo Molnar 
3266133dc4c3SIngo Molnar 	while (fgets(line, sizeof(line), fp)) {
326732858480SArnaldo Carvalho de Melo 		p = skip_spaces(line);
3268133dc4c3SIngo Molnar 		if (strlen(p) == 0)
3269133dc4c3SIngo Molnar 			continue;
3270133dc4c3SIngo Molnar 		if (*p != '#')
3271133dc4c3SIngo Molnar 			continue;
3272133dc4c3SIngo Molnar 		p++;
3273133dc4c3SIngo Molnar 		if (strlen(p) && *p == '!')
3274133dc4c3SIngo Molnar 			continue;
3275133dc4c3SIngo Molnar 
327632858480SArnaldo Carvalho de Melo 		p = skip_spaces(p);
3277133dc4c3SIngo Molnar 		if (strlen(p) && p[strlen(p) - 1] == '\n')
3278133dc4c3SIngo Molnar 			p[strlen(p) - 1] = '\0';
3279133dc4c3SIngo Molnar 
3280133dc4c3SIngo Molnar 		if (!strncmp(p, "description:", strlen("description:"))) {
3281133dc4c3SIngo Molnar 			p += strlen("description:");
328232858480SArnaldo Carvalho de Melo 			desc->half_liner = strdup(skip_spaces(p));
3283133dc4c3SIngo Molnar 			continue;
3284133dc4c3SIngo Molnar 		}
3285133dc4c3SIngo Molnar 
3286133dc4c3SIngo Molnar 		if (!strncmp(p, "args:", strlen("args:"))) {
3287133dc4c3SIngo Molnar 			p += strlen("args:");
328832858480SArnaldo Carvalho de Melo 			desc->args = strdup(skip_spaces(p));
3289133dc4c3SIngo Molnar 			continue;
3290133dc4c3SIngo Molnar 		}
3291133dc4c3SIngo Molnar 	}
3292133dc4c3SIngo Molnar 
3293133dc4c3SIngo Molnar 	fclose(fp);
3294133dc4c3SIngo Molnar 
3295133dc4c3SIngo Molnar 	return 0;
3296133dc4c3SIngo Molnar }
3297133dc4c3SIngo Molnar 
get_script_root(struct dirent * script_dirent,const char * suffix)329838efb539SRobert Richter static char *get_script_root(struct dirent *script_dirent, const char *suffix)
329938efb539SRobert Richter {
330038efb539SRobert Richter 	char *script_root, *str;
330138efb539SRobert Richter 
330238efb539SRobert Richter 	script_root = strdup(script_dirent->d_name);
330338efb539SRobert Richter 	if (!script_root)
330438efb539SRobert Richter 		return NULL;
330538efb539SRobert Richter 
330638efb539SRobert Richter 	str = (char *)ends_with(script_root, suffix);
330738efb539SRobert Richter 	if (!str) {
330838efb539SRobert Richter 		free(script_root);
330938efb539SRobert Richter 		return NULL;
331038efb539SRobert Richter 	}
331138efb539SRobert Richter 
331238efb539SRobert Richter 	*str = '\0';
331338efb539SRobert Richter 	return script_root;
331438efb539SRobert Richter }
331538efb539SRobert Richter 
list_available_scripts(const struct option * opt __maybe_unused,const char * s __maybe_unused,int unset __maybe_unused)33161d037ca1SIrina Tirdea static int list_available_scripts(const struct option *opt __maybe_unused,
33171d037ca1SIrina Tirdea 				  const char *s __maybe_unused,
33181d037ca1SIrina Tirdea 				  int unset __maybe_unused)
3319133dc4c3SIngo Molnar {
3320a5e8e825SArnaldo Carvalho de Melo 	struct dirent *script_dirent, *lang_dirent;
3321e590e46bSIan Rogers 	char *buf, *scripts_path, *script_path, *lang_path, *first_half;
3322133dc4c3SIngo Molnar 	DIR *scripts_dir, *lang_dir;
3323133dc4c3SIngo Molnar 	struct script_desc *desc;
3324133dc4c3SIngo Molnar 	char *script_root;
3325133dc4c3SIngo Molnar 
3326e590e46bSIan Rogers 	buf = malloc(3 * MAXPATHLEN + BUFSIZ);
3327e590e46bSIan Rogers 	if (!buf) {
3328e590e46bSIan Rogers 		pr_err("malloc failed\n");
3329e590e46bSIan Rogers 		exit(-1);
3330e590e46bSIan Rogers 	}
3331e590e46bSIan Rogers 	scripts_path = buf;
3332e590e46bSIan Rogers 	script_path = buf + MAXPATHLEN;
3333e590e46bSIan Rogers 	lang_path = buf + 2 * MAXPATHLEN;
3334e590e46bSIan Rogers 	first_half = buf + 3 * MAXPATHLEN;
3335e590e46bSIan Rogers 
333646113a54SJosh Poimboeuf 	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3337133dc4c3SIngo Molnar 
3338133dc4c3SIngo Molnar 	scripts_dir = opendir(scripts_path);
333988ded4d8SHe Kuang 	if (!scripts_dir) {
334088ded4d8SHe Kuang 		fprintf(stdout,
334188ded4d8SHe Kuang 			"open(%s) failed.\n"
334288ded4d8SHe Kuang 			"Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",
334388ded4d8SHe Kuang 			scripts_path);
3344e590e46bSIan Rogers 		free(buf);
334588ded4d8SHe Kuang 		exit(-1);
334688ded4d8SHe Kuang 	}
3347133dc4c3SIngo Molnar 
3348a5e8e825SArnaldo Carvalho de Melo 	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
334977f18153SJiri Olsa 		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
3350a5e8e825SArnaldo Carvalho de Melo 			  lang_dirent->d_name);
3351133dc4c3SIngo Molnar 		lang_dir = opendir(lang_path);
3352133dc4c3SIngo Molnar 		if (!lang_dir)
3353133dc4c3SIngo Molnar 			continue;
3354133dc4c3SIngo Molnar 
3355a5e8e825SArnaldo Carvalho de Melo 		for_each_script(lang_path, lang_dir, script_dirent) {
3356a5e8e825SArnaldo Carvalho de Melo 			script_root = get_script_root(script_dirent, REPORT_SUFFIX);
335738efb539SRobert Richter 			if (script_root) {
3358133dc4c3SIngo Molnar 				desc = script_desc__findnew(script_root);
335977f18153SJiri Olsa 				scnprintf(script_path, MAXPATHLEN, "%s/%s",
3360a5e8e825SArnaldo Carvalho de Melo 					  lang_path, script_dirent->d_name);
3361133dc4c3SIngo Molnar 				read_script_info(desc, script_path);
3362133dc4c3SIngo Molnar 				free(script_root);
3363133dc4c3SIngo Molnar 			}
3364133dc4c3SIngo Molnar 		}
336538efb539SRobert Richter 	}
3366133dc4c3SIngo Molnar 
3367133dc4c3SIngo Molnar 	fprintf(stdout, "List of available trace scripts:\n");
3368133dc4c3SIngo Molnar 	list_for_each_entry(desc, &script_descs, node) {
3369133dc4c3SIngo Molnar 		sprintf(first_half, "%s %s", desc->name,
3370133dc4c3SIngo Molnar 			desc->args ? desc->args : "");
3371133dc4c3SIngo Molnar 		fprintf(stdout, "  %-36s %s\n", first_half,
3372133dc4c3SIngo Molnar 			desc->half_liner ? desc->half_liner : "");
3373133dc4c3SIngo Molnar 	}
3374133dc4c3SIngo Molnar 
3375e590e46bSIan Rogers 	free(buf);
3376133dc4c3SIngo Molnar 	exit(0);
3377133dc4c3SIngo Molnar }
3378133dc4c3SIngo Molnar 
add_dlarg(const struct option * opt __maybe_unused,const char * s,int unset __maybe_unused)33793d032a25SAdrian Hunter static int add_dlarg(const struct option *opt __maybe_unused,
33803d032a25SAdrian Hunter 		     const char *s, int unset __maybe_unused)
33813d032a25SAdrian Hunter {
33823d032a25SAdrian Hunter 	char *arg = strdup(s);
33833d032a25SAdrian Hunter 	void *a;
33843d032a25SAdrian Hunter 
33853d032a25SAdrian Hunter 	if (!arg)
33863d032a25SAdrian Hunter 		return -1;
33873d032a25SAdrian Hunter 
33883d032a25SAdrian Hunter 	a = realloc(dlargv, sizeof(dlargv[0]) * (dlargc + 1));
33893d032a25SAdrian Hunter 	if (!a) {
33903d032a25SAdrian Hunter 		free(arg);
33913d032a25SAdrian Hunter 		return -1;
33923d032a25SAdrian Hunter 	}
33933d032a25SAdrian Hunter 
33943d032a25SAdrian Hunter 	dlargv = a;
33953d032a25SAdrian Hunter 	dlargv[dlargc++] = arg;
33963d032a25SAdrian Hunter 
33973d032a25SAdrian Hunter 	return 0;
33983d032a25SAdrian Hunter }
33993d032a25SAdrian Hunter 
free_dlarg(void)34003d032a25SAdrian Hunter static void free_dlarg(void)
34013d032a25SAdrian Hunter {
34023d032a25SAdrian Hunter 	while (dlargc--)
34033d032a25SAdrian Hunter 		free(dlargv[dlargc]);
34043d032a25SAdrian Hunter 	free(dlargv);
34053d032a25SAdrian Hunter }
34063d032a25SAdrian Hunter 
3407e5f3705eSFeng Tang /*
340849e639e2SFeng Tang  * Some scripts specify the required events in their "xxx-record" file,
340949e639e2SFeng Tang  * this function will check if the events in perf.data match those
341049e639e2SFeng Tang  * mentioned in the "xxx-record".
341149e639e2SFeng Tang  *
341249e639e2SFeng Tang  * Fixme: All existing "xxx-record" are all in good formats "-e event ",
341349e639e2SFeng Tang  * which is covered well now. And new parsing code should be added to
34144d39c89fSIngo Molnar  * cover the future complex formats like event groups etc.
341549e639e2SFeng Tang  */
check_ev_match(char * dir_name,char * scriptname,struct perf_session * session)341649e639e2SFeng Tang static int check_ev_match(char *dir_name, char *scriptname,
341749e639e2SFeng Tang 			struct perf_session *session)
341849e639e2SFeng Tang {
341949e639e2SFeng Tang 	char filename[MAXPATHLEN], evname[128];
342049e639e2SFeng Tang 	char line[BUFSIZ], *p;
342132dcd021SJiri Olsa 	struct evsel *pos;
342249e639e2SFeng Tang 	int match, len;
342349e639e2SFeng Tang 	FILE *fp;
342449e639e2SFeng Tang 
342577f18153SJiri Olsa 	scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname);
342649e639e2SFeng Tang 
342749e639e2SFeng Tang 	fp = fopen(filename, "r");
342849e639e2SFeng Tang 	if (!fp)
342949e639e2SFeng Tang 		return -1;
343049e639e2SFeng Tang 
343149e639e2SFeng Tang 	while (fgets(line, sizeof(line), fp)) {
343232858480SArnaldo Carvalho de Melo 		p = skip_spaces(line);
343349e639e2SFeng Tang 		if (*p == '#')
343449e639e2SFeng Tang 			continue;
343549e639e2SFeng Tang 
343649e639e2SFeng Tang 		while (strlen(p)) {
343749e639e2SFeng Tang 			p = strstr(p, "-e");
343849e639e2SFeng Tang 			if (!p)
343949e639e2SFeng Tang 				break;
344049e639e2SFeng Tang 
344149e639e2SFeng Tang 			p += 2;
344232858480SArnaldo Carvalho de Melo 			p = skip_spaces(p);
344349e639e2SFeng Tang 			len = strcspn(p, " \t");
344449e639e2SFeng Tang 			if (!len)
344549e639e2SFeng Tang 				break;
344649e639e2SFeng Tang 
344749e639e2SFeng Tang 			snprintf(evname, len + 1, "%s", p);
344849e639e2SFeng Tang 
344949e639e2SFeng Tang 			match = 0;
3450e5cadb93SArnaldo Carvalho de Melo 			evlist__for_each_entry(session->evlist, pos) {
34518ab2e96dSArnaldo Carvalho de Melo 				if (!strcmp(evsel__name(pos), evname)) {
345249e639e2SFeng Tang 					match = 1;
345349e639e2SFeng Tang 					break;
345449e639e2SFeng Tang 				}
345549e639e2SFeng Tang 			}
345649e639e2SFeng Tang 
345749e639e2SFeng Tang 			if (!match) {
345849e639e2SFeng Tang 				fclose(fp);
345949e639e2SFeng Tang 				return -1;
346049e639e2SFeng Tang 			}
346149e639e2SFeng Tang 		}
346249e639e2SFeng Tang 	}
346349e639e2SFeng Tang 
346449e639e2SFeng Tang 	fclose(fp);
346549e639e2SFeng Tang 	return 0;
346649e639e2SFeng Tang }
346749e639e2SFeng Tang 
346849e639e2SFeng Tang /*
3469e5f3705eSFeng Tang  * Return -1 if none is found, otherwise the actual scripts number.
3470e5f3705eSFeng Tang  *
3471e5f3705eSFeng Tang  * Currently the only user of this function is the script browser, which
3472e5f3705eSFeng Tang  * will list all statically runnable scripts, select one, execute it and
3473e5f3705eSFeng Tang  * show the output in a perf browser.
3474e5f3705eSFeng Tang  */
find_scripts(char ** scripts_array,char ** scripts_path_array,int num,int pathlen)3475905e4affSAndi Kleen int find_scripts(char **scripts_array, char **scripts_path_array, int num,
3476905e4affSAndi Kleen 		 int pathlen)
3477e5f3705eSFeng Tang {
3478a5e8e825SArnaldo Carvalho de Melo 	struct dirent *script_dirent, *lang_dirent;
347949e639e2SFeng Tang 	char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
3480e5f3705eSFeng Tang 	DIR *scripts_dir, *lang_dir;
348149e639e2SFeng Tang 	struct perf_session *session;
34828ceb41d7SJiri Olsa 	struct perf_data data = {
3483f5fc1412SJiri Olsa 		.path = input_name,
3484f5fc1412SJiri Olsa 		.mode = PERF_DATA_MODE_READ,
3485f5fc1412SJiri Olsa 	};
3486e5f3705eSFeng Tang 	char *temp;
3487e5f3705eSFeng Tang 	int i = 0;
3488e5f3705eSFeng Tang 
34892681bd85SNamhyung Kim 	session = perf_session__new(&data, NULL);
34906ef81c55SMamatha Inamdar 	if (IS_ERR(session))
34916ef81c55SMamatha Inamdar 		return PTR_ERR(session);
349249e639e2SFeng Tang 
349346113a54SJosh Poimboeuf 	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3494e5f3705eSFeng Tang 
3495e5f3705eSFeng Tang 	scripts_dir = opendir(scripts_path);
349649e639e2SFeng Tang 	if (!scripts_dir) {
349749e639e2SFeng Tang 		perf_session__delete(session);
3498e5f3705eSFeng Tang 		return -1;
349949e639e2SFeng Tang 	}
3500e5f3705eSFeng Tang 
3501a5e8e825SArnaldo Carvalho de Melo 	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
350277f18153SJiri Olsa 		scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
3503a5e8e825SArnaldo Carvalho de Melo 			  lang_dirent->d_name);
350490ce61b9SJin Yao #ifndef HAVE_LIBPERL_SUPPORT
3505e5f3705eSFeng Tang 		if (strstr(lang_path, "perl"))
3506e5f3705eSFeng Tang 			continue;
3507e5f3705eSFeng Tang #endif
350890ce61b9SJin Yao #ifndef HAVE_LIBPYTHON_SUPPORT
3509e5f3705eSFeng Tang 		if (strstr(lang_path, "python"))
3510e5f3705eSFeng Tang 			continue;
3511e5f3705eSFeng Tang #endif
3512e5f3705eSFeng Tang 
3513e5f3705eSFeng Tang 		lang_dir = opendir(lang_path);
3514e5f3705eSFeng Tang 		if (!lang_dir)
3515e5f3705eSFeng Tang 			continue;
3516e5f3705eSFeng Tang 
3517a5e8e825SArnaldo Carvalho de Melo 		for_each_script(lang_path, lang_dir, script_dirent) {
3518e5f3705eSFeng Tang 			/* Skip those real time scripts: xxxtop.p[yl] */
3519a5e8e825SArnaldo Carvalho de Melo 			if (strstr(script_dirent->d_name, "top."))
3520e5f3705eSFeng Tang 				continue;
3521905e4affSAndi Kleen 			if (i >= num)
3522905e4affSAndi Kleen 				break;
3523905e4affSAndi Kleen 			snprintf(scripts_path_array[i], pathlen, "%s/%s",
3524905e4affSAndi Kleen 				lang_path,
3525a5e8e825SArnaldo Carvalho de Melo 				script_dirent->d_name);
3526a5e8e825SArnaldo Carvalho de Melo 			temp = strchr(script_dirent->d_name, '.');
3527e5f3705eSFeng Tang 			snprintf(scripts_array[i],
3528a5e8e825SArnaldo Carvalho de Melo 				(temp - script_dirent->d_name) + 1,
3529a5e8e825SArnaldo Carvalho de Melo 				"%s", script_dirent->d_name);
353049e639e2SFeng Tang 
353149e639e2SFeng Tang 			if (check_ev_match(lang_path,
353249e639e2SFeng Tang 					scripts_array[i], session))
353349e639e2SFeng Tang 				continue;
353449e639e2SFeng Tang 
3535e5f3705eSFeng Tang 			i++;
3536e5f3705eSFeng Tang 		}
353749e639e2SFeng Tang 		closedir(lang_dir);
3538e5f3705eSFeng Tang 	}
3539e5f3705eSFeng Tang 
354049e639e2SFeng Tang 	closedir(scripts_dir);
354149e639e2SFeng Tang 	perf_session__delete(session);
3542e5f3705eSFeng Tang 	return i;
3543e5f3705eSFeng Tang }
3544e5f3705eSFeng Tang 
get_script_path(const char * script_root,const char * suffix)3545133dc4c3SIngo Molnar static char *get_script_path(const char *script_root, const char *suffix)
3546133dc4c3SIngo Molnar {
3547a5e8e825SArnaldo Carvalho de Melo 	struct dirent *script_dirent, *lang_dirent;
3548133dc4c3SIngo Molnar 	char scripts_path[MAXPATHLEN];
3549133dc4c3SIngo Molnar 	char script_path[MAXPATHLEN];
3550133dc4c3SIngo Molnar 	DIR *scripts_dir, *lang_dir;
3551133dc4c3SIngo Molnar 	char lang_path[MAXPATHLEN];
355238efb539SRobert Richter 	char *__script_root;
3553133dc4c3SIngo Molnar 
355446113a54SJosh Poimboeuf 	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3555133dc4c3SIngo Molnar 
3556133dc4c3SIngo Molnar 	scripts_dir = opendir(scripts_path);
3557133dc4c3SIngo Molnar 	if (!scripts_dir)
3558133dc4c3SIngo Molnar 		return NULL;
3559133dc4c3SIngo Molnar 
3560a5e8e825SArnaldo Carvalho de Melo 	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
356177f18153SJiri Olsa 		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
3562a5e8e825SArnaldo Carvalho de Melo 			  lang_dirent->d_name);
3563133dc4c3SIngo Molnar 		lang_dir = opendir(lang_path);
3564133dc4c3SIngo Molnar 		if (!lang_dir)
3565133dc4c3SIngo Molnar 			continue;
3566133dc4c3SIngo Molnar 
3567a5e8e825SArnaldo Carvalho de Melo 		for_each_script(lang_path, lang_dir, script_dirent) {
3568a5e8e825SArnaldo Carvalho de Melo 			__script_root = get_script_root(script_dirent, suffix);
356938efb539SRobert Richter 			if (__script_root && !strcmp(script_root, __script_root)) {
357038efb539SRobert Richter 				free(__script_root);
3571946ef2a2SNamhyung Kim 				closedir(scripts_dir);
357277f18153SJiri Olsa 				scnprintf(script_path, MAXPATHLEN, "%s/%s",
3573a5e8e825SArnaldo Carvalho de Melo 					  lang_path, script_dirent->d_name);
357427486a85SAndreas Gerstmayr 				closedir(lang_dir);
357538efb539SRobert Richter 				return strdup(script_path);
3576133dc4c3SIngo Molnar 			}
3577133dc4c3SIngo Molnar 			free(__script_root);
3578133dc4c3SIngo Molnar 		}
3579946ef2a2SNamhyung Kim 		closedir(lang_dir);
3580133dc4c3SIngo Molnar 	}
3581946ef2a2SNamhyung Kim 	closedir(scripts_dir);
3582133dc4c3SIngo Molnar 
358338efb539SRobert Richter 	return NULL;
3584133dc4c3SIngo Molnar }
3585133dc4c3SIngo Molnar 
is_top_script(const char * script_path)3586133dc4c3SIngo Molnar static bool is_top_script(const char *script_path)
3587133dc4c3SIngo Molnar {
35888524711dSYang Li 	return ends_with(script_path, "top") != NULL;
3589133dc4c3SIngo Molnar }
3590133dc4c3SIngo Molnar 
has_required_arg(char * script_path)3591133dc4c3SIngo Molnar static int has_required_arg(char *script_path)
3592133dc4c3SIngo Molnar {
3593133dc4c3SIngo Molnar 	struct script_desc *desc;
3594133dc4c3SIngo Molnar 	int n_args = 0;
3595133dc4c3SIngo Molnar 	char *p;
3596133dc4c3SIngo Molnar 
3597133dc4c3SIngo Molnar 	desc = script_desc__new(NULL);
3598133dc4c3SIngo Molnar 
3599133dc4c3SIngo Molnar 	if (read_script_info(desc, script_path))
3600133dc4c3SIngo Molnar 		goto out;
3601133dc4c3SIngo Molnar 
3602133dc4c3SIngo Molnar 	if (!desc->args)
3603133dc4c3SIngo Molnar 		goto out;
3604133dc4c3SIngo Molnar 
3605133dc4c3SIngo Molnar 	for (p = desc->args; *p; p++)
3606133dc4c3SIngo Molnar 		if (*p == '<')
3607133dc4c3SIngo Molnar 			n_args++;
3608133dc4c3SIngo Molnar out:
3609133dc4c3SIngo Molnar 	script_desc__delete(desc);
3610133dc4c3SIngo Molnar 
3611133dc4c3SIngo Molnar 	return n_args;
3612133dc4c3SIngo Molnar }
3613133dc4c3SIngo Molnar 
have_cmd(int argc,const char ** argv)3614d54b1a9eSDavid Ahern static int have_cmd(int argc, const char **argv)
3615133dc4c3SIngo Molnar {
3616133dc4c3SIngo Molnar 	char **__argv = malloc(sizeof(const char *) * argc);
3617133dc4c3SIngo Molnar 
3618d54b1a9eSDavid Ahern 	if (!__argv) {
3619d54b1a9eSDavid Ahern 		pr_err("malloc failed\n");
3620d54b1a9eSDavid Ahern 		return -1;
3621d54b1a9eSDavid Ahern 	}
3622d54b1a9eSDavid Ahern 
3623133dc4c3SIngo Molnar 	memcpy(__argv, argv, sizeof(const char *) * argc);
3624133dc4c3SIngo Molnar 	argc = parse_options(argc, (const char **)__argv, record_options,
3625133dc4c3SIngo Molnar 			     NULL, PARSE_OPT_STOP_AT_NON_OPTION);
3626133dc4c3SIngo Molnar 	free(__argv);
3627133dc4c3SIngo Molnar 
3628d54b1a9eSDavid Ahern 	system_wide = (argc == 0);
3629d54b1a9eSDavid Ahern 
3630d54b1a9eSDavid Ahern 	return 0;
3631133dc4c3SIngo Molnar }
3632133dc4c3SIngo Molnar 
script__setup_sample_type(struct perf_script * script)36337322d6c9SJiri Olsa static void script__setup_sample_type(struct perf_script *script)
36347322d6c9SJiri Olsa {
36357322d6c9SJiri Olsa 	struct perf_session *session = script->session;
3636b3c2cc2bSArnaldo Carvalho de Melo 	u64 sample_type = evlist__combined_sample_type(session->evlist);
36377322d6c9SJiri Olsa 
3638aa8db3e4SAlexandre Truong 	callchain_param_setup(sample_type, perf_env__arch(session->machines.host.env));
3639680d125cSKan Liang 
3640680d125cSKan Liang 	if (script->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) {
3641680d125cSKan Liang 		pr_warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"
3642680d125cSKan Liang 			   "Please apply --call-graph lbr when recording.\n");
3643680d125cSKan Liang 		script->stitch_lbr = false;
3644680d125cSKan Liang 	}
36457322d6c9SJiri Olsa }
36467322d6c9SJiri Olsa 
process_stat_round_event(struct perf_session * session,union perf_event * event)364789f1688aSJiri Olsa static int process_stat_round_event(struct perf_session *session,
364889f1688aSJiri Olsa 				    union perf_event *event)
3649e099eba8SJiri Olsa {
365072932371SJiri Olsa 	struct perf_record_stat_round *round = &event->stat_round;
365132dcd021SJiri Olsa 	struct evsel *counter;
3652e099eba8SJiri Olsa 
3653e5cadb93SArnaldo Carvalho de Melo 	evlist__for_each_entry(session->evlist, counter) {
3654e099eba8SJiri Olsa 		perf_stat_process_counter(&stat_config, counter);
3655e099eba8SJiri Olsa 		process_stat(counter, round->time);
3656e099eba8SJiri Olsa 	}
3657e099eba8SJiri Olsa 
3658e099eba8SJiri Olsa 	process_stat_interval(round->time);
3659e099eba8SJiri Olsa 	return 0;
3660e099eba8SJiri Olsa }
3661e099eba8SJiri Olsa 
process_stat_config_event(struct perf_session * session __maybe_unused,union perf_event * event)366289f1688aSJiri Olsa static int process_stat_config_event(struct perf_session *session __maybe_unused,
366389f1688aSJiri Olsa 				     union perf_event *event)
366491a2c3d5SJiri Olsa {
366591a2c3d5SJiri Olsa 	perf_event__read_stat_config(&stat_config, &event->stat_config);
36662fe65759SSandipan Das 
36672fe65759SSandipan Das 	/*
36682fe65759SSandipan Das 	 * Aggregation modes are not used since post-processing scripts are
36692fe65759SSandipan Das 	 * supposed to take care of such requirements
36702fe65759SSandipan Das 	 */
36712fe65759SSandipan Das 	stat_config.aggr_mode = AGGR_NONE;
36722fe65759SSandipan Das 
367391a2c3d5SJiri Olsa 	return 0;
367491a2c3d5SJiri Olsa }
367591a2c3d5SJiri Olsa 
set_maps(struct perf_script * script)3676cfc8874aSJiri Olsa static int set_maps(struct perf_script *script)
3677cfc8874aSJiri Olsa {
367863503dbaSJiri Olsa 	struct evlist *evlist = script->session->evlist;
3679cfc8874aSJiri Olsa 
3680cfc8874aSJiri Olsa 	if (!script->cpus || !script->threads)
3681cfc8874aSJiri Olsa 		return 0;
3682cfc8874aSJiri Olsa 
3683cfc8874aSJiri Olsa 	if (WARN_ONCE(script->allocated, "stats double allocation\n"))
3684cfc8874aSJiri Olsa 		return -EINVAL;
3685cfc8874aSJiri Olsa 
3686453fa030SJiri Olsa 	perf_evlist__set_maps(&evlist->core, script->cpus, script->threads);
3687cfc8874aSJiri Olsa 
36881f297a6eSNamhyung Kim 	if (evlist__alloc_stats(&stat_config, evlist, /*alloc_raw=*/true))
3689cfc8874aSJiri Olsa 		return -ENOMEM;
3690cfc8874aSJiri Olsa 
3691cfc8874aSJiri Olsa 	script->allocated = true;
3692cfc8874aSJiri Olsa 	return 0;
3693cfc8874aSJiri Olsa }
3694cfc8874aSJiri Olsa 
3695cfc8874aSJiri Olsa static
process_thread_map_event(struct perf_session * session,union perf_event * event)369689f1688aSJiri Olsa int process_thread_map_event(struct perf_session *session,
369789f1688aSJiri Olsa 			     union perf_event *event)
3698cfc8874aSJiri Olsa {
369989f1688aSJiri Olsa 	struct perf_tool *tool = session->tool;
3700cfc8874aSJiri Olsa 	struct perf_script *script = container_of(tool, struct perf_script, tool);
3701cfc8874aSJiri Olsa 
370252f28b7bSAdrian Hunter 	if (dump_trace)
370352f28b7bSAdrian Hunter 		perf_event__fprintf_thread_map(event, stdout);
370452f28b7bSAdrian Hunter 
3705cfc8874aSJiri Olsa 	if (script->threads) {
3706cfc8874aSJiri Olsa 		pr_warning("Extra thread map event, ignoring.\n");
3707cfc8874aSJiri Olsa 		return 0;
3708cfc8874aSJiri Olsa 	}
3709cfc8874aSJiri Olsa 
3710cfc8874aSJiri Olsa 	script->threads = thread_map__new_event(&event->thread_map);
3711cfc8874aSJiri Olsa 	if (!script->threads)
3712cfc8874aSJiri Olsa 		return -ENOMEM;
3713cfc8874aSJiri Olsa 
3714cfc8874aSJiri Olsa 	return set_maps(script);
3715cfc8874aSJiri Olsa }
3716cfc8874aSJiri Olsa 
3717cfc8874aSJiri Olsa static
process_cpu_map_event(struct perf_session * session,union perf_event * event)371889f1688aSJiri Olsa int process_cpu_map_event(struct perf_session *session,
371989f1688aSJiri Olsa 			  union perf_event *event)
3720cfc8874aSJiri Olsa {
372189f1688aSJiri Olsa 	struct perf_tool *tool = session->tool;
3722cfc8874aSJiri Olsa 	struct perf_script *script = container_of(tool, struct perf_script, tool);
3723cfc8874aSJiri Olsa 
372452f28b7bSAdrian Hunter 	if (dump_trace)
372552f28b7bSAdrian Hunter 		perf_event__fprintf_cpu_map(event, stdout);
372652f28b7bSAdrian Hunter 
3727cfc8874aSJiri Olsa 	if (script->cpus) {
3728cfc8874aSJiri Olsa 		pr_warning("Extra cpu map event, ignoring.\n");
3729cfc8874aSJiri Olsa 		return 0;
3730cfc8874aSJiri Olsa 	}
3731cfc8874aSJiri Olsa 
3732cfc8874aSJiri Olsa 	script->cpus = cpu_map__new_data(&event->cpu_map.data);
3733cfc8874aSJiri Olsa 	if (!script->cpus)
3734cfc8874aSJiri Olsa 		return -ENOMEM;
3735cfc8874aSJiri Olsa 
3736cfc8874aSJiri Olsa 	return set_maps(script);
3737cfc8874aSJiri Olsa }
3738cfc8874aSJiri Olsa 
process_feature_event(struct perf_session * session,union perf_event * event)373989f1688aSJiri Olsa static int process_feature_event(struct perf_session *session,
374089f1688aSJiri Olsa 				 union perf_event *event)
374192ead7eeSRavi Bangoria {
374292ead7eeSRavi Bangoria 	if (event->feat.feat_id < HEADER_LAST_FEATURE)
374389f1688aSJiri Olsa 		return perf_event__process_feature(session, event);
374492ead7eeSRavi Bangoria 	return 0;
374592ead7eeSRavi Bangoria }
374692ead7eeSRavi Bangoria 
3747fa48c892SArnaldo Carvalho de Melo #ifdef HAVE_AUXTRACE_SUPPORT
perf_script__process_auxtrace_info(struct perf_session * session,union perf_event * event)374889f1688aSJiri Olsa static int perf_script__process_auxtrace_info(struct perf_session *session,
374989f1688aSJiri Olsa 					      union perf_event *event)
3750fa48c892SArnaldo Carvalho de Melo {
375189f1688aSJiri Olsa 	struct perf_tool *tool = session->tool;
375289f1688aSJiri Olsa 
375389f1688aSJiri Olsa 	int ret = perf_event__process_auxtrace_info(session, event);
3754fa48c892SArnaldo Carvalho de Melo 
3755fa48c892SArnaldo Carvalho de Melo 	if (ret == 0) {
3756fa48c892SArnaldo Carvalho de Melo 		struct perf_script *script = container_of(tool, struct perf_script, tool);
3757fa48c892SArnaldo Carvalho de Melo 
3758fa48c892SArnaldo Carvalho de Melo 		ret = perf_script__setup_per_event_dump(script);
3759fa48c892SArnaldo Carvalho de Melo 	}
3760fa48c892SArnaldo Carvalho de Melo 
3761fa48c892SArnaldo Carvalho de Melo 	return ret;
3762fa48c892SArnaldo Carvalho de Melo }
3763fa48c892SArnaldo Carvalho de Melo #else
3764fa48c892SArnaldo Carvalho de Melo #define perf_script__process_auxtrace_info 0
3765fa48c892SArnaldo Carvalho de Melo #endif
3766fa48c892SArnaldo Carvalho de Melo 
parse_insn_trace(const struct option * opt __maybe_unused,const char * str,int unset __maybe_unused)3767b585ebdbSAndi Kleen static int parse_insn_trace(const struct option *opt __maybe_unused,
37680ea11a11SChangbin Du 			    const char *str, int unset __maybe_unused)
3769b585ebdbSAndi Kleen {
37700ea11a11SChangbin Du 	const char *fields = "+insn,-event,-period";
37710ea11a11SChangbin Du 	int ret;
37720ea11a11SChangbin Du 
37730ea11a11SChangbin Du 	if (str) {
37740ea11a11SChangbin Du 		if (strcmp(str, "disasm") == 0)
37750ea11a11SChangbin Du 			fields = "+disasm,-event,-period";
37760ea11a11SChangbin Du 		else if (strlen(str) != 0 && strcmp(str, "raw") != 0) {
37770ea11a11SChangbin Du 			fprintf(stderr, "Only accept raw|disasm\n");
37780ea11a11SChangbin Du 			return -EINVAL;
37790ea11a11SChangbin Du 		}
37800ea11a11SChangbin Du 	}
37810ea11a11SChangbin Du 
37820ea11a11SChangbin Du 	ret = parse_output_fields(NULL, fields, 0);
37830ea11a11SChangbin Du 	if (ret < 0)
37840ea11a11SChangbin Du 		return ret;
37850ea11a11SChangbin Du 
3786*b30c9b11SAdrian Hunter 	itrace_parse_synth_opts(opt, "i0nse", 0);
378752bab886SAndi Kleen 	symbol_conf.nanosecs = true;
3788b585ebdbSAndi Kleen 	return 0;
3789b585ebdbSAndi Kleen }
3790b585ebdbSAndi Kleen 
parse_xed(const struct option * opt __maybe_unused,const char * str __maybe_unused,int unset __maybe_unused)3791b585ebdbSAndi Kleen static int parse_xed(const struct option *opt __maybe_unused,
3792b585ebdbSAndi Kleen 		     const char *str __maybe_unused,
3793b585ebdbSAndi Kleen 		     int unset __maybe_unused)
3794b585ebdbSAndi Kleen {
37958c3e05c8SAndi Kleen 	if (isatty(1))
3796b585ebdbSAndi Kleen 		force_pager("xed -F insn: -A -64 | less");
37978c3e05c8SAndi Kleen 	else
37988c3e05c8SAndi Kleen 		force_pager("xed -F insn: -A -64");
3799b585ebdbSAndi Kleen 	return 0;
3800b585ebdbSAndi Kleen }
3801b585ebdbSAndi Kleen 
parse_call_trace(const struct option * opt __maybe_unused,const char * str __maybe_unused,int unset __maybe_unused)3802d1b1552eSAndi Kleen static int parse_call_trace(const struct option *opt __maybe_unused,
3803d1b1552eSAndi Kleen 			    const char *str __maybe_unused,
3804d1b1552eSAndi Kleen 			    int unset __maybe_unused)
3805d1b1552eSAndi Kleen {
3806d1b1552eSAndi Kleen 	parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent", 0);
3807d1b1552eSAndi Kleen 	itrace_parse_synth_opts(opt, "cewp", 0);
380852bab886SAndi Kleen 	symbol_conf.nanosecs = true;
38091c492422SJiri Olsa 	symbol_conf.pad_output_len_dso = 50;
3810d1b1552eSAndi Kleen 	return 0;
3811d1b1552eSAndi Kleen }
3812d1b1552eSAndi Kleen 
parse_callret_trace(const struct option * opt __maybe_unused,const char * str __maybe_unused,int unset __maybe_unused)3813d1b1552eSAndi Kleen static int parse_callret_trace(const struct option *opt __maybe_unused,
3814d1b1552eSAndi Kleen 			    const char *str __maybe_unused,
3815d1b1552eSAndi Kleen 			    int unset __maybe_unused)
3816d1b1552eSAndi Kleen {
3817d1b1552eSAndi Kleen 	parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent,+flags", 0);
3818d1b1552eSAndi Kleen 	itrace_parse_synth_opts(opt, "crewp", 0);
381952bab886SAndi Kleen 	symbol_conf.nanosecs = true;
3820d1b1552eSAndi Kleen 	return 0;
3821d1b1552eSAndi Kleen }
3822d1b1552eSAndi Kleen 
cmd_script(int argc,const char ** argv)3823b0ad8ea6SArnaldo Carvalho de Melo int cmd_script(int argc, const char **argv)
3824133dc4c3SIngo Molnar {
382569b6470eSArnaldo Carvalho de Melo 	bool show_full_info = false;
3826e90debddSJiri Olsa 	bool header = false;
3827e90debddSJiri Olsa 	bool header_only = false;
38286cc870f0SNamhyung Kim 	bool script_started = false;
382957190e38SAdrian Hunter 	bool unsorted_dump = false;
3830133dc4c3SIngo Molnar 	char *rec_script_path = NULL;
3831133dc4c3SIngo Molnar 	char *rep_script_path = NULL;
3832133dc4c3SIngo Molnar 	struct perf_session *session;
38334eb06815SAndi Kleen 	struct itrace_synth_opts itrace_synth_opts = {
38344eb06815SAndi Kleen 		.set = false,
38354eb06815SAndi Kleen 		.default_no_sample = true,
38364eb06815SAndi Kleen 	};
38373ab481a1SAndi Kleen 	struct utsname uts;
3838133dc4c3SIngo Molnar 	char *script_path = NULL;
3839291961fcSAdrian Hunter 	const char *dlfilter_file = NULL;
3840133dc4c3SIngo Molnar 	const char **__argv;
38416cc870f0SNamhyung Kim 	int i, j, err = 0;
38426f3e5edaSAdrian Hunter 	struct perf_script script = {
38436f3e5edaSAdrian Hunter 		.tool = {
38446f3e5edaSAdrian Hunter 			.sample		 = process_sample_event,
38456f3e5edaSAdrian Hunter 			.mmap		 = perf_event__process_mmap,
38466f3e5edaSAdrian Hunter 			.mmap2		 = perf_event__process_mmap2,
38476f3e5edaSAdrian Hunter 			.comm		 = perf_event__process_comm,
3848f3b3614aSHari Bathini 			.namespaces	 = perf_event__process_namespaces,
3849160d4af9SNamhyung Kim 			.cgroup		 = perf_event__process_cgroup,
38506f3e5edaSAdrian Hunter 			.exit		 = perf_event__process_exit,
38516f3e5edaSAdrian Hunter 			.fork		 = perf_event__process_fork,
38527ea95727SAdrian Hunter 			.attr		 = process_attr,
385391daee30SJiri Olsa 			.event_update   = perf_event__process_event_update,
3854378ef0f5SIan Rogers #ifdef HAVE_LIBTRACEEVENT
38556f3e5edaSAdrian Hunter 			.tracing_data	 = perf_event__process_tracing_data,
3856378ef0f5SIan Rogers #endif
385792ead7eeSRavi Bangoria 			.feature	 = process_feature_event,
38586f3e5edaSAdrian Hunter 			.build_id	 = perf_event__process_build_id,
38597a680eb9SAdrian Hunter 			.id_index	 = perf_event__process_id_index,
3860fa48c892SArnaldo Carvalho de Melo 			.auxtrace_info	 = perf_script__process_auxtrace_info,
38617a680eb9SAdrian Hunter 			.auxtrace	 = perf_event__process_auxtrace,
38627a680eb9SAdrian Hunter 			.auxtrace_error	 = perf_event__process_auxtrace_error,
3863e099eba8SJiri Olsa 			.stat		 = perf_event__process_stat_event,
3864e099eba8SJiri Olsa 			.stat_round	 = process_stat_round_event,
386591a2c3d5SJiri Olsa 			.stat_config	 = process_stat_config_event,
3866cfc8874aSJiri Olsa 			.thread_map	 = process_thread_map_event,
3867cfc8874aSJiri Olsa 			.cpu_map	 = process_cpu_map_event,
3868538d9c18SStephen Brennan 			.throttle	 = process_throttle_event,
3869538d9c18SStephen Brennan 			.unthrottle	 = process_throttle_event,
38700a8cb85cSJiri Olsa 			.ordered_events	 = true,
38716f3e5edaSAdrian Hunter 			.ordering_requires_timestamps = true,
38726f3e5edaSAdrian Hunter 		},
38736f3e5edaSAdrian Hunter 	};
38748ceb41d7SJiri Olsa 	struct perf_data data = {
387506af0f2cSYunlong Song 		.mode = PERF_DATA_MODE_READ,
387606af0f2cSYunlong Song 	};
387769b6470eSArnaldo Carvalho de Melo 	const struct option options[] = {
387869b6470eSArnaldo Carvalho de Melo 	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
387969b6470eSArnaldo Carvalho de Melo 		    "dump raw trace in ASCII"),
388057190e38SAdrian Hunter 	OPT_BOOLEAN(0, "dump-unsorted-raw-trace", &unsorted_dump,
388157190e38SAdrian Hunter 		    "dump unsorted raw trace in ASCII"),
388269b6470eSArnaldo Carvalho de Melo 	OPT_INCR('v', "verbose", &verbose,
388369b6470eSArnaldo Carvalho de Melo 		 "be more verbose (show symbol address, etc)"),
388469b6470eSArnaldo Carvalho de Melo 	OPT_BOOLEAN('L', "Latency", &latency_format,
388569b6470eSArnaldo Carvalho de Melo 		    "show latency attributes (irqs/preemption disabled, etc)"),
388669b6470eSArnaldo Carvalho de Melo 	OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
388769b6470eSArnaldo Carvalho de Melo 			   list_available_scripts),
3888638e2b99SAdrian Hunter 	OPT_CALLBACK_NOOPT(0, "list-dlfilters", NULL, NULL, "list available dlfilters",
3889638e2b99SAdrian Hunter 			   list_available_dlfilters),
389069b6470eSArnaldo Carvalho de Melo 	OPT_CALLBACK('s', "script", NULL, "name",
389169b6470eSArnaldo Carvalho de Melo 		     "script file name (lang:script name, script name, or *)",
389269b6470eSArnaldo Carvalho de Melo 		     parse_scriptname),
389369b6470eSArnaldo Carvalho de Melo 	OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
389469b6470eSArnaldo Carvalho de Melo 		   "generate perf-script.xx script in specified language"),
3895291961fcSAdrian Hunter 	OPT_STRING(0, "dlfilter", &dlfilter_file, "file", "filter .so file name"),
38963d032a25SAdrian Hunter 	OPT_CALLBACK(0, "dlarg", NULL, "argument", "filter argument",
38973d032a25SAdrian Hunter 		     add_dlarg),
389869b6470eSArnaldo Carvalho de Melo 	OPT_STRING('i', "input", &input_name, "file", "input file name"),
389969b6470eSArnaldo Carvalho de Melo 	OPT_BOOLEAN('d', "debug-mode", &debug_mode,
390069b6470eSArnaldo Carvalho de Melo 		   "do various checks like samples ordering and lost events"),
3901e90debddSJiri Olsa 	OPT_BOOLEAN(0, "header", &header, "Show data header."),
3902e90debddSJiri Olsa 	OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),
390369b6470eSArnaldo Carvalho de Melo 	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
390469b6470eSArnaldo Carvalho de Melo 		   "file", "vmlinux pathname"),
390569b6470eSArnaldo Carvalho de Melo 	OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
390669b6470eSArnaldo Carvalho de Melo 		   "file", "kallsyms pathname"),
390769b6470eSArnaldo Carvalho de Melo 	OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
390869b6470eSArnaldo Carvalho de Melo 		    "When printing symbols do not display call chain"),
3909a7066709SHe Kuang 	OPT_CALLBACK(0, "symfs", NULL, "directory",
3910a7066709SHe Kuang 		     "Look for files with symbols relative to this directory",
3911a7066709SHe Kuang 		     symbol__config_symfs),
391206af0f2cSYunlong Song 	OPT_CALLBACK('F', "fields", NULL, "str",
391369b6470eSArnaldo Carvalho de Melo 		     "comma separated output fields prepend with 'type:'. "
391436ce5651SAndi Kleen 		     "+field to add and -field to remove."
39151405720dSAdrian Hunter 		     "Valid types: hw,sw,trace,raw,synth. "
3916af9eb56bSChangbin Du 		     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,dsoff"
391710e9cec9SRavi Bangoria 		     "addr,symoff,srcline,period,iregs,uregs,brstack,"
3918d7931070SRavi Bangoria 		     "brstacksym,flags,data_src,weight,bpf-output,brstackinsn,"
3919d7931070SRavi Bangoria 		     "brstackinsnlen,brstackoff,callindent,insn,insnlen,synth,"
3920d7931070SRavi Bangoria 		     "phys_addr,metric,misc,srccode,ipc,tod,data_page_size,"
392117f248aaSKan Liang 		     "code_page_size,ins_lat,machine_pid,vcpu,cgroup,retire_lat",
392248d02a1dSAndi Kleen 		     parse_output_fields),
392369b6470eSArnaldo Carvalho de Melo 	OPT_BOOLEAN('a', "all-cpus", &system_wide,
392469b6470eSArnaldo Carvalho de Melo 		    "system-wide collection from all CPUs"),
39254b799a9bSJin Yao 	OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
39264b799a9bSJin Yao 		   "only consider symbols in these DSOs"),
392769b6470eSArnaldo Carvalho de Melo 	OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
392869b6470eSArnaldo Carvalho de Melo 		   "only consider these symbols"),
392961d9fc44SJin Yao 	OPT_INTEGER(0, "addr-range", &symbol_conf.addr_range,
393061d9fc44SJin Yao 		    "Use with -S to list traced records within address range"),
39310ea11a11SChangbin Du 	OPT_CALLBACK_OPTARG(0, "insn-trace", &itrace_synth_opts, NULL, "raw|disasm",
3932b585ebdbSAndi Kleen 			"Decode instructions from itrace", parse_insn_trace),
3933b585ebdbSAndi Kleen 	OPT_CALLBACK_OPTARG(0, "xed", NULL, NULL, NULL,
3934b585ebdbSAndi Kleen 			"Run xed disassembler on output", parse_xed),
3935d1b1552eSAndi Kleen 	OPT_CALLBACK_OPTARG(0, "call-trace", &itrace_synth_opts, NULL, NULL,
3936ae4e4a0bSshaomin Deng 			"Decode calls from itrace", parse_call_trace),
3937d1b1552eSAndi Kleen 	OPT_CALLBACK_OPTARG(0, "call-ret-trace", &itrace_synth_opts, NULL, NULL,
3938d1b1552eSAndi Kleen 			"Decode calls and returns from itrace", parse_callret_trace),
393999f753f0SAndi Kleen 	OPT_STRING(0, "graph-function", &symbol_conf.graph_function, "symbol[,symbol...]",
394099f753f0SAndi Kleen 			"Only print symbols and callees with --call-trace/--call-ret-trace"),
394164eff7d9SDavid Ahern 	OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]",
394264eff7d9SDavid Ahern 		   "Stop display of callgraph at these symbols"),
394369b6470eSArnaldo Carvalho de Melo 	OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
394469b6470eSArnaldo Carvalho de Melo 	OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
394569b6470eSArnaldo Carvalho de Melo 		   "only display events for these comms"),
3946e03eaa40SDavid Ahern 	OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
3947e03eaa40SDavid Ahern 		   "only consider symbols in these pids"),
3948e03eaa40SDavid Ahern 	OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
3949e03eaa40SDavid Ahern 		   "only consider symbols in these tids"),
39506125cc8dSArnaldo Carvalho de Melo 	OPT_UINTEGER(0, "max-stack", &scripting_max_stack,
39516125cc8dSArnaldo Carvalho de Melo 		     "Set the maximum stack depth when parsing the callchain, "
39526125cc8dSArnaldo Carvalho de Melo 		     "anything beyond the specified depth will be ignored. "
39534cb93446SArnaldo Carvalho de Melo 		     "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
395490b10f47SAndi Kleen 	OPT_BOOLEAN(0, "reltime", &reltime, "Show time stamps relative to start"),
395526567ed7SHagen Paul Pfeifer 	OPT_BOOLEAN(0, "deltatime", &deltatime, "Show time stamps relative to previous event"),
395669b6470eSArnaldo Carvalho de Melo 	OPT_BOOLEAN('I', "show-info", &show_full_info,
395769b6470eSArnaldo Carvalho de Melo 		    "display extended information from perf.data file"),
395869b6470eSArnaldo Carvalho de Melo 	OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
395969b6470eSArnaldo Carvalho de Melo 		    "Show the path of [kernel.kallsyms]"),
3960ad7ebb9aSNamhyung Kim 	OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events,
3961ad7ebb9aSNamhyung Kim 		    "Show the fork/comm/exit events"),
3962ba1ddf42SNamhyung Kim 	OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
3963ba1ddf42SNamhyung Kim 		    "Show the mmap events"),
39647c14898bSAdrian Hunter 	OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
39657c14898bSAdrian Hunter 		    "Show context switch events (if recorded)"),
396696a44bbcSHari Bathini 	OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
396796a44bbcSHari Bathini 		    "Show namespace events (if recorded)"),
3968160d4af9SNamhyung Kim 	OPT_BOOLEAN('\0', "show-cgroup-events", &script.show_cgroup_events,
3969160d4af9SNamhyung Kim 		    "Show cgroup events (if recorded)"),
39703d7c27b6SJiri Olsa 	OPT_BOOLEAN('\0', "show-lost-events", &script.show_lost_events,
39713d7c27b6SJiri Olsa 		    "Show lost events (if recorded)"),
39723233b37aSJiri Olsa 	OPT_BOOLEAN('\0', "show-round-events", &script.show_round_events,
39733233b37aSJiri Olsa 		    "Show round events (if recorded)"),
3974490c8cc9SJiri Olsa 	OPT_BOOLEAN('\0', "show-bpf-events", &script.show_bpf_events,
3975490c8cc9SJiri Olsa 		    "Show bpf related events (if recorded)"),
397692ecf3a6SAdrian Hunter 	OPT_BOOLEAN('\0', "show-text-poke-events", &script.show_text_poke_events,
397792ecf3a6SAdrian Hunter 		    "Show text poke related events (if recorded)"),
3978a14390fdSArnaldo Carvalho de Melo 	OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
3979a14390fdSArnaldo Carvalho de Melo 		    "Dump trace output to files named by the monitored events"),
3980be3d466cSYannick Brosseau 	OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
398148d02a1dSAndi Kleen 	OPT_INTEGER(0, "max-blocks", &max_blocks,
398248d02a1dSAndi Kleen 		    "Maximum number of code blocks to dump with brstackinsn"),
398352bab886SAndi Kleen 	OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs,
398483e19860SAdrian Hunter 		    "Use 9 decimal places when displaying time"),
39857a680eb9SAdrian Hunter 	OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
3986c12e039dSAndi Kleen 			    "Instruction Tracing options\n" ITRACE_HELP,
39877a680eb9SAdrian Hunter 			    itrace_parse_synth_opts),
3988a9710ba0SAndi Kleen 	OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
3989a9710ba0SAndi Kleen 			"Show full source file name path for source lines"),
399077e0070dSMark Drayton 	OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
399177e0070dSMark Drayton 			"Enable symbol demangling"),
399277e0070dSMark Drayton 	OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
399377e0070dSMark Drayton 			"Enable kernel symbol demangling"),
3994a91f4c47SDavid Ahern 	OPT_STRING(0, "time", &script.time_str, "str",
3995a91f4c47SDavid Ahern 		   "Time span of interest (start,stop)"),
3996325fbff5SNamhyung Kim 	OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
3997325fbff5SNamhyung Kim 		    "Show inline function"),
399815a108afSArnaldo Carvalho de Melo 	OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory",
399915a108afSArnaldo Carvalho de Melo 		   "guest mount directory under which every guest os"
400015a108afSArnaldo Carvalho de Melo 		   " instance has a subdir"),
400115a108afSArnaldo Carvalho de Melo 	OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name,
400215a108afSArnaldo Carvalho de Melo 		   "file", "file saving guest os vmlinux"),
400315a108afSArnaldo Carvalho de Melo 	OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms,
400415a108afSArnaldo Carvalho de Melo 		   "file", "file saving guest os /proc/kallsyms"),
400515a108afSArnaldo Carvalho de Melo 	OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
400615a108afSArnaldo Carvalho de Melo 		   "file", "file saving guest os /proc/modules"),
40075b208144SAdrian Hunter 	OPT_BOOLEAN(0, "guest-code", &symbol_conf.guest_code,
40085b208144SAdrian Hunter 		    "Guest code can be found in hypervisor process"),
4009680d125cSKan Liang 	OPT_BOOLEAN('\0', "stitch-lbr", &script.stitch_lbr,
4010680d125cSKan Liang 		    "Enable LBR callgraph stitching approach"),
4011add3a719SArnaldo Carvalho de Melo 	OPTS_EVSWITCH(&script.evswitch),
401269b6470eSArnaldo Carvalho de Melo 	OPT_END()
401369b6470eSArnaldo Carvalho de Melo 	};
401440cae2b7SYunlong Song 	const char * const script_subcommands[] = { "record", "report", NULL };
401540cae2b7SYunlong Song 	const char *script_usage[] = {
401669b6470eSArnaldo Carvalho de Melo 		"perf script [<options>]",
401769b6470eSArnaldo Carvalho de Melo 		"perf script [<options>] record <script> [<record-options>] <command>",
401869b6470eSArnaldo Carvalho de Melo 		"perf script [<options>] report <script> [script-args]",
401969b6470eSArnaldo Carvalho de Melo 		"perf script [<options>] <script> [<record-options>] <command>",
402069b6470eSArnaldo Carvalho de Melo 		"perf script [<options>] <top-script> [script-args]",
402169b6470eSArnaldo Carvalho de Melo 		NULL
402269b6470eSArnaldo Carvalho de Melo 	};
4023133dc4c3SIngo Molnar 
40240a7c74eaSArnaldo Carvalho de Melo 	perf_set_singlethreaded();
40250a7c74eaSArnaldo Carvalho de Melo 
4026133dc4c3SIngo Molnar 	setup_scripting();
4027133dc4c3SIngo Molnar 
402840cae2b7SYunlong Song 	argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
4029133dc4c3SIngo Molnar 			     PARSE_OPT_STOP_AT_NON_OPTION);
4030133dc4c3SIngo Molnar 
403115a108afSArnaldo Carvalho de Melo 	if (symbol_conf.guestmount ||
403215a108afSArnaldo Carvalho de Melo 	    symbol_conf.default_guest_vmlinux_name ||
403315a108afSArnaldo Carvalho de Melo 	    symbol_conf.default_guest_kallsyms ||
40345b208144SAdrian Hunter 	    symbol_conf.default_guest_modules ||
40355b208144SAdrian Hunter 	    symbol_conf.guest_code) {
403615a108afSArnaldo Carvalho de Melo 		/*
403715a108afSArnaldo Carvalho de Melo 		 * Enable guest sample processing.
403815a108afSArnaldo Carvalho de Melo 		 */
403915a108afSArnaldo Carvalho de Melo 		perf_guest = true;
404015a108afSArnaldo Carvalho de Melo 	}
404115a108afSArnaldo Carvalho de Melo 
40422d4f2799SJiri Olsa 	data.path  = input_name;
40438ceb41d7SJiri Olsa 	data.force = symbol_conf.force;
4044f5fc1412SJiri Olsa 
404557190e38SAdrian Hunter 	if (unsorted_dump) {
404657190e38SAdrian Hunter 		dump_trace = true;
404757190e38SAdrian Hunter 		script.tool.ordered_events = false;
404857190e38SAdrian Hunter 	}
404957190e38SAdrian Hunter 
40507cc72553SJames Clark 	if (symbol__validate_sym_arguments())
40517cc72553SJames Clark 		return -1;
40527cc72553SJames Clark 
4053ae0f4eb3SWei Li 	if (argc > 1 && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
4054133dc4c3SIngo Molnar 		rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
4055133dc4c3SIngo Molnar 		if (!rec_script_path)
4056b0ad8ea6SArnaldo Carvalho de Melo 			return cmd_record(argc, argv);
4057133dc4c3SIngo Molnar 	}
4058133dc4c3SIngo Molnar 
4059ae0f4eb3SWei Li 	if (argc > 1 && strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
4060133dc4c3SIngo Molnar 		rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
4061133dc4c3SIngo Molnar 		if (!rep_script_path) {
4062133dc4c3SIngo Molnar 			fprintf(stderr,
4063133dc4c3SIngo Molnar 				"Please specify a valid report script"
4064133dc4c3SIngo Molnar 				"(see 'perf script -l' for listing)\n");
4065133dc4c3SIngo Molnar 			return -1;
4066133dc4c3SIngo Molnar 		}
4067133dc4c3SIngo Molnar 	}
4068133dc4c3SIngo Molnar 
406926567ed7SHagen Paul Pfeifer 	if (reltime && deltatime) {
407026567ed7SHagen Paul Pfeifer 		fprintf(stderr,
407126567ed7SHagen Paul Pfeifer 			"reltime and deltatime - the two don't get along well. "
407226567ed7SHagen Paul Pfeifer 			"Please limit to --reltime or --deltatime.\n");
407326567ed7SHagen Paul Pfeifer 		return -1;
407426567ed7SHagen Paul Pfeifer 	}
407526567ed7SHagen Paul Pfeifer 
40761c5c25b3SAdrian Hunter 	if ((itrace_synth_opts.callchain || itrace_synth_opts.add_callchain) &&
40773c5b645fSAdrian Hunter 	    itrace_synth_opts.callchain_sz > scripting_max_stack)
40783c5b645fSAdrian Hunter 		scripting_max_stack = itrace_synth_opts.callchain_sz;
40793c5b645fSAdrian Hunter 
4080133dc4c3SIngo Molnar 	/* make sure PERF_EXEC_PATH is set for scripts */
408146113a54SJosh Poimboeuf 	set_argv_exec_path(get_argv_exec_path());
4082133dc4c3SIngo Molnar 
4083133dc4c3SIngo Molnar 	if (argc && !script_name && !rec_script_path && !rep_script_path) {
4084133dc4c3SIngo Molnar 		int live_pipe[2];
4085133dc4c3SIngo Molnar 		int rep_args;
4086133dc4c3SIngo Molnar 		pid_t pid;
4087133dc4c3SIngo Molnar 
4088133dc4c3SIngo Molnar 		rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);
4089133dc4c3SIngo Molnar 		rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
4090133dc4c3SIngo Molnar 
4091133dc4c3SIngo Molnar 		if (!rec_script_path && !rep_script_path) {
40926ea4b5dbSAdrian Hunter 			script_name = find_script(argv[0]);
40936ea4b5dbSAdrian Hunter 			if (script_name) {
40946ea4b5dbSAdrian Hunter 				argc -= 1;
40956ea4b5dbSAdrian Hunter 				argv += 1;
40966ea4b5dbSAdrian Hunter 				goto script_found;
40976ea4b5dbSAdrian Hunter 			}
4098c7118369SNamhyung Kim 			usage_with_options_msg(script_usage, options,
4099c7118369SNamhyung Kim 				"Couldn't find script `%s'\n\n See perf"
4100133dc4c3SIngo Molnar 				" script -l for available scripts.\n", argv[0]);
4101133dc4c3SIngo Molnar 		}
4102133dc4c3SIngo Molnar 
4103133dc4c3SIngo Molnar 		if (is_top_script(argv[0])) {
4104133dc4c3SIngo Molnar 			rep_args = argc - 1;
4105133dc4c3SIngo Molnar 		} else {
4106133dc4c3SIngo Molnar 			int rec_args;
4107133dc4c3SIngo Molnar 
4108133dc4c3SIngo Molnar 			rep_args = has_required_arg(rep_script_path);
4109133dc4c3SIngo Molnar 			rec_args = (argc - 1) - rep_args;
4110133dc4c3SIngo Molnar 			if (rec_args < 0) {
4111c7118369SNamhyung Kim 				usage_with_options_msg(script_usage, options,
4112c7118369SNamhyung Kim 					"`%s' script requires options."
4113133dc4c3SIngo Molnar 					"\n\n See perf script -l for available "
4114133dc4c3SIngo Molnar 					"scripts and options.\n", argv[0]);
4115133dc4c3SIngo Molnar 			}
4116133dc4c3SIngo Molnar 		}
4117133dc4c3SIngo Molnar 
4118133dc4c3SIngo Molnar 		if (pipe(live_pipe) < 0) {
4119133dc4c3SIngo Molnar 			perror("failed to create pipe");
4120d54b1a9eSDavid Ahern 			return -1;
4121133dc4c3SIngo Molnar 		}
4122133dc4c3SIngo Molnar 
4123133dc4c3SIngo Molnar 		pid = fork();
4124133dc4c3SIngo Molnar 		if (pid < 0) {
4125133dc4c3SIngo Molnar 			perror("failed to fork");
4126d54b1a9eSDavid Ahern 			return -1;
4127133dc4c3SIngo Molnar 		}
4128133dc4c3SIngo Molnar 
4129133dc4c3SIngo Molnar 		if (!pid) {
4130133dc4c3SIngo Molnar 			j = 0;
4131133dc4c3SIngo Molnar 
4132133dc4c3SIngo Molnar 			dup2(live_pipe[1], 1);
4133133dc4c3SIngo Molnar 			close(live_pipe[0]);
4134133dc4c3SIngo Molnar 
4135317df650SRobert Richter 			if (is_top_script(argv[0])) {
4136317df650SRobert Richter 				system_wide = true;
4137317df650SRobert Richter 			} else if (!system_wide) {
4138d54b1a9eSDavid Ahern 				if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
4139d54b1a9eSDavid Ahern 					err = -1;
4140d54b1a9eSDavid Ahern 					goto out;
4141d54b1a9eSDavid Ahern 				}
4142317df650SRobert Richter 			}
4143133dc4c3SIngo Molnar 
4144133dc4c3SIngo Molnar 			__argv = malloc((argc + 6) * sizeof(const char *));
4145d54b1a9eSDavid Ahern 			if (!__argv) {
4146d54b1a9eSDavid Ahern 				pr_err("malloc failed\n");
4147d54b1a9eSDavid Ahern 				err = -ENOMEM;
4148d54b1a9eSDavid Ahern 				goto out;
4149d54b1a9eSDavid Ahern 			}
4150133dc4c3SIngo Molnar 
4151133dc4c3SIngo Molnar 			__argv[j++] = "/bin/sh";
4152133dc4c3SIngo Molnar 			__argv[j++] = rec_script_path;
4153133dc4c3SIngo Molnar 			if (system_wide)
4154133dc4c3SIngo Molnar 				__argv[j++] = "-a";
4155133dc4c3SIngo Molnar 			__argv[j++] = "-q";
4156133dc4c3SIngo Molnar 			__argv[j++] = "-o";
4157133dc4c3SIngo Molnar 			__argv[j++] = "-";
4158133dc4c3SIngo Molnar 			for (i = rep_args + 1; i < argc; i++)
4159133dc4c3SIngo Molnar 				__argv[j++] = argv[i];
4160133dc4c3SIngo Molnar 			__argv[j++] = NULL;
4161133dc4c3SIngo Molnar 
4162133dc4c3SIngo Molnar 			execvp("/bin/sh", (char **)__argv);
4163133dc4c3SIngo Molnar 			free(__argv);
4164133dc4c3SIngo Molnar 			exit(-1);
4165133dc4c3SIngo Molnar 		}
4166133dc4c3SIngo Molnar 
4167133dc4c3SIngo Molnar 		dup2(live_pipe[0], 0);
4168133dc4c3SIngo Molnar 		close(live_pipe[1]);
4169133dc4c3SIngo Molnar 
4170133dc4c3SIngo Molnar 		__argv = malloc((argc + 4) * sizeof(const char *));
4171d54b1a9eSDavid Ahern 		if (!__argv) {
4172d54b1a9eSDavid Ahern 			pr_err("malloc failed\n");
4173d54b1a9eSDavid Ahern 			err = -ENOMEM;
4174d54b1a9eSDavid Ahern 			goto out;
4175d54b1a9eSDavid Ahern 		}
4176d54b1a9eSDavid Ahern 
4177133dc4c3SIngo Molnar 		j = 0;
4178133dc4c3SIngo Molnar 		__argv[j++] = "/bin/sh";
4179133dc4c3SIngo Molnar 		__argv[j++] = rep_script_path;
4180133dc4c3SIngo Molnar 		for (i = 1; i < rep_args + 1; i++)
4181133dc4c3SIngo Molnar 			__argv[j++] = argv[i];
4182133dc4c3SIngo Molnar 		__argv[j++] = "-i";
4183133dc4c3SIngo Molnar 		__argv[j++] = "-";
4184133dc4c3SIngo Molnar 		__argv[j++] = NULL;
4185133dc4c3SIngo Molnar 
4186133dc4c3SIngo Molnar 		execvp("/bin/sh", (char **)__argv);
4187133dc4c3SIngo Molnar 		free(__argv);
4188133dc4c3SIngo Molnar 		exit(-1);
4189133dc4c3SIngo Molnar 	}
41906ea4b5dbSAdrian Hunter script_found:
4191133dc4c3SIngo Molnar 	if (rec_script_path)
4192133dc4c3SIngo Molnar 		script_path = rec_script_path;
4193133dc4c3SIngo Molnar 	if (rep_script_path)
4194133dc4c3SIngo Molnar 		script_path = rep_script_path;
4195133dc4c3SIngo Molnar 
4196133dc4c3SIngo Molnar 	if (script_path) {
4197133dc4c3SIngo Molnar 		j = 0;
4198133dc4c3SIngo Molnar 
4199317df650SRobert Richter 		if (!rec_script_path)
4200317df650SRobert Richter 			system_wide = false;
4201d54b1a9eSDavid Ahern 		else if (!system_wide) {
4202d54b1a9eSDavid Ahern 			if (have_cmd(argc - 1, &argv[1]) != 0) {
4203d54b1a9eSDavid Ahern 				err = -1;
4204d54b1a9eSDavid Ahern 				goto out;
4205d54b1a9eSDavid Ahern 			}
4206d54b1a9eSDavid Ahern 		}
4207133dc4c3SIngo Molnar 
4208133dc4c3SIngo Molnar 		__argv = malloc((argc + 2) * sizeof(const char *));
4209d54b1a9eSDavid Ahern 		if (!__argv) {
4210d54b1a9eSDavid Ahern 			pr_err("malloc failed\n");
4211d54b1a9eSDavid Ahern 			err = -ENOMEM;
4212d54b1a9eSDavid Ahern 			goto out;
4213d54b1a9eSDavid Ahern 		}
4214d54b1a9eSDavid Ahern 
4215133dc4c3SIngo Molnar 		__argv[j++] = "/bin/sh";
4216133dc4c3SIngo Molnar 		__argv[j++] = script_path;
4217133dc4c3SIngo Molnar 		if (system_wide)
4218133dc4c3SIngo Molnar 			__argv[j++] = "-a";
4219133dc4c3SIngo Molnar 		for (i = 2; i < argc; i++)
4220133dc4c3SIngo Molnar 			__argv[j++] = argv[i];
4221133dc4c3SIngo Molnar 		__argv[j++] = NULL;
4222133dc4c3SIngo Molnar 
4223133dc4c3SIngo Molnar 		execvp("/bin/sh", (char **)__argv);
4224133dc4c3SIngo Molnar 		free(__argv);
4225133dc4c3SIngo Molnar 		exit(-1);
4226133dc4c3SIngo Molnar 	}
4227133dc4c3SIngo Molnar 
4228291961fcSAdrian Hunter 	if (dlfilter_file) {
42293d032a25SAdrian Hunter 		dlfilter = dlfilter__new(dlfilter_file, dlargc, dlargv);
4230291961fcSAdrian Hunter 		if (!dlfilter)
4231291961fcSAdrian Hunter 			return -1;
4232291961fcSAdrian Hunter 	}
4233291961fcSAdrian Hunter 
4234c1c9b969SMilian Wolff 	if (!script_name) {
4235133dc4c3SIngo Molnar 		setup_pager();
4236c1c9b969SMilian Wolff 		use_browser = 0;
4237c1c9b969SMilian Wolff 	}
4238133dc4c3SIngo Molnar 
42392681bd85SNamhyung Kim 	session = perf_session__new(&data, &script.tool);
42406ef81c55SMamatha Inamdar 	if (IS_ERR(session))
42416ef81c55SMamatha Inamdar 		return PTR_ERR(session);
4242133dc4c3SIngo Molnar 
4243e90debddSJiri Olsa 	if (header || header_only) {
4244114f709eSDavid Carrillo-Cisneros 		script.tool.show_feat_hdr = SHOW_FEAT_HEADER;
4245e90debddSJiri Olsa 		perf_session__fprintf_info(session, stdout, show_full_info);
4246e90debddSJiri Olsa 		if (header_only)
42476cc870f0SNamhyung Kim 			goto out_delete;
4248e90debddSJiri Olsa 	}
4249114f709eSDavid Carrillo-Cisneros 	if (show_full_info)
4250114f709eSDavid Carrillo-Cisneros 		script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
4251e90debddSJiri Olsa 
42520a7e6d1bSNamhyung Kim 	if (symbol__init(&session->header.env) < 0)
425338520dc3SNamhyung Kim 		goto out_delete;
425438520dc3SNamhyung Kim 
42553ab481a1SAndi Kleen 	uname(&uts);
425629c77550SSong Liu 	if (data.is_pipe) { /* Assume pipe_mode indicates native_arch */
42573ab481a1SAndi Kleen 		native_arch = true;
425829c77550SSong Liu 	} else if (session->header.env.arch) {
425929c77550SSong Liu 		if (!strcmp(uts.machine, session->header.env.arch))
426029c77550SSong Liu 			native_arch = true;
426129c77550SSong Liu 		else if (!strcmp(uts.machine, "x86_64") &&
426229c77550SSong Liu 			 !strcmp(session->header.env.arch, "i386"))
426329c77550SSong Liu 			native_arch = true;
426429c77550SSong Liu 	}
42653ab481a1SAndi Kleen 
42666f3e5edaSAdrian Hunter 	script.session = session;
42677322d6c9SJiri Olsa 	script__setup_sample_type(&script);
42686f3e5edaSAdrian Hunter 
426999f753f0SAndi Kleen 	if ((output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT) ||
427099f753f0SAndi Kleen 	    symbol_conf.graph_function)
4271e216708dSAdrian Hunter 		itrace_synth_opts.thread_stack = true;
4272e216708dSAdrian Hunter 
42737a680eb9SAdrian Hunter 	session->itrace_synth_opts = &itrace_synth_opts;
42747a680eb9SAdrian Hunter 
42755d67be97SAnton Blanchard 	if (cpu_list) {
42766cc870f0SNamhyung Kim 		err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
42776cc870f0SNamhyung Kim 		if (err < 0)
42786cc870f0SNamhyung Kim 			goto out_delete;
4279644e0840SAdrian Hunter 		itrace_synth_opts.cpu_bitmap = cpu_bitmap;
42805d67be97SAnton Blanchard 	}
42815d67be97SAnton Blanchard 
42821424dc96SDavid Ahern 	if (!no_callchain)
4283c0230b2bSDavid Ahern 		symbol_conf.use_callchain = true;
4284c0230b2bSDavid Ahern 	else
4285c0230b2bSDavid Ahern 		symbol_conf.use_callchain = false;
4286c0230b2bSDavid Ahern 
4287378ef0f5SIan Rogers #ifdef HAVE_LIBTRACEEVENT
42889ee67421SArnaldo Carvalho de Melo 	if (session->tevent.pevent &&
4289ece2a4f4STzvetomir Stoyanov (VMware) 	    tep_set_function_resolver(session->tevent.pevent,
4290ccb3a829SArnaldo Carvalho de Melo 				      machine__resolve_kernel_addr,
4291ccb3a829SArnaldo Carvalho de Melo 				      &session->machines.host) < 0) {
4292ccb3a829SArnaldo Carvalho de Melo 		pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
4293db49bc15SChristophe JAILLET 		err = -1;
4294db49bc15SChristophe JAILLET 		goto out_delete;
4295ccb3a829SArnaldo Carvalho de Melo 	}
4296378ef0f5SIan Rogers #endif
4297133dc4c3SIngo Molnar 	if (generate_script_lang) {
4298133dc4c3SIngo Molnar 		struct stat perf_stat;
4299745f43e3SDavid Ahern 		int input;
4300133dc4c3SIngo Molnar 
43012c9e45f7SDavid Ahern 		if (output_set_by_user()) {
4302745f43e3SDavid Ahern 			fprintf(stderr,
4303745f43e3SDavid Ahern 				"custom fields not supported for generated scripts");
43046cc870f0SNamhyung Kim 			err = -EINVAL;
43056cc870f0SNamhyung Kim 			goto out_delete;
4306745f43e3SDavid Ahern 		}
4307745f43e3SDavid Ahern 
43082d4f2799SJiri Olsa 		input = open(data.path, O_RDONLY);	/* input_name */
4309133dc4c3SIngo Molnar 		if (input < 0) {
43106cc870f0SNamhyung Kim 			err = -errno;
4311133dc4c3SIngo Molnar 			perror("failed to open file");
43126cc870f0SNamhyung Kim 			goto out_delete;
4313133dc4c3SIngo Molnar 		}
4314133dc4c3SIngo Molnar 
4315133dc4c3SIngo Molnar 		err = fstat(input, &perf_stat);
4316133dc4c3SIngo Molnar 		if (err < 0) {
4317133dc4c3SIngo Molnar 			perror("failed to stat file");
43186cc870f0SNamhyung Kim 			goto out_delete;
4319133dc4c3SIngo Molnar 		}
4320133dc4c3SIngo Molnar 
4321133dc4c3SIngo Molnar 		if (!perf_stat.st_size) {
4322133dc4c3SIngo Molnar 			fprintf(stderr, "zero-sized file, nothing to do!\n");
43236cc870f0SNamhyung Kim 			goto out_delete;
4324133dc4c3SIngo Molnar 		}
4325133dc4c3SIngo Molnar 
4326133dc4c3SIngo Molnar 		scripting_ops = script_spec__lookup(generate_script_lang);
4327133dc4c3SIngo Molnar 		if (!scripting_ops) {
4328133dc4c3SIngo Molnar 			fprintf(stderr, "invalid language specifier");
43296cc870f0SNamhyung Kim 			err = -ENOENT;
43306cc870f0SNamhyung Kim 			goto out_delete;
4331133dc4c3SIngo Molnar 		}
4332378ef0f5SIan Rogers #ifdef HAVE_LIBTRACEEVENT
433329f5ffd3SJiri Olsa 		err = scripting_ops->generate_script(session->tevent.pevent,
4334da378962SArnaldo Carvalho de Melo 						     "perf-script");
4335378ef0f5SIan Rogers #else
4336378ef0f5SIan Rogers 		err = scripting_ops->generate_script(NULL, "perf-script");
4337378ef0f5SIan Rogers #endif
43386cc870f0SNamhyung Kim 		goto out_delete;
4339133dc4c3SIngo Molnar 	}
4340133dc4c3SIngo Molnar 
4341291961fcSAdrian Hunter 	err = dlfilter__start(dlfilter, session);
4342291961fcSAdrian Hunter 	if (err)
4343291961fcSAdrian Hunter 		goto out_delete;
4344291961fcSAdrian Hunter 
4345133dc4c3SIngo Molnar 	if (script_name) {
434667e50ce0SAdrian Hunter 		err = scripting_ops->start_script(script_name, argc, argv, session);
4347133dc4c3SIngo Molnar 		if (err)
43486cc870f0SNamhyung Kim 			goto out_delete;
4349133dc4c3SIngo Molnar 		pr_debug("perf script started with script %s\n\n", script_name);
43506cc870f0SNamhyung Kim 		script_started = true;
4351133dc4c3SIngo Molnar 	}
4352133dc4c3SIngo Molnar 
43539cbdb702SDavid Ahern 
43549cbdb702SDavid Ahern 	err = perf_session__check_output_opt(session);
43559cbdb702SDavid Ahern 	if (err < 0)
43566cc870f0SNamhyung Kim 		goto out_delete;
43579cbdb702SDavid Ahern 
4358284c4e18SJin Yao 	if (script.time_str) {
4359b3509b6eSAndi Kleen 		err = perf_time__parse_for_ranges_reltime(script.time_str, session,
4360284c4e18SJin Yao 						  &script.ptime_range,
4361284c4e18SJin Yao 						  &script.range_size,
4362b3509b6eSAndi Kleen 						  &script.range_num,
4363b3509b6eSAndi Kleen 						  reltime);
4364284c4e18SJin Yao 		if (err < 0)
4365cc2ef584SJin Yao 			goto out_delete;
4366400ae981SAdrian Hunter 
4367400ae981SAdrian Hunter 		itrace_synth_opts__set_time_range(&itrace_synth_opts,
4368400ae981SAdrian Hunter 						  script.ptime_range,
4369400ae981SAdrian Hunter 						  script.range_num);
4370cc2ef584SJin Yao 	}
4371cc2ef584SJin Yao 
4372124e02beSArnaldo Carvalho de Melo 	err = evswitch__init(&script.evswitch, session->evlist, stderr);
4373124e02beSArnaldo Carvalho de Melo 	if (err)
4374f90a2417SArnaldo Carvalho de Melo 		goto out_delete;
4375dd41f660SArnaldo Carvalho de Melo 
4376b13b04d9SMilian Wolff 	if (zstd_init(&(session->zstd_data), 0) < 0)
4377b13b04d9SMilian Wolff 		pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");
4378b13b04d9SMilian Wolff 
43796f3e5edaSAdrian Hunter 	err = __cmd_script(&script);
4380133dc4c3SIngo Molnar 
4381d445dd2aSAdrian Hunter 	flush_scripting();
4382d445dd2aSAdrian Hunter 
43836cc870f0SNamhyung Kim out_delete:
4384400ae981SAdrian Hunter 	if (script.ptime_range) {
4385400ae981SAdrian Hunter 		itrace_synth_opts__clear_time_range(&itrace_synth_opts);
4386cc2ef584SJin Yao 		zfree(&script.ptime_range);
4387400ae981SAdrian Hunter 	}
4388cc2ef584SJin Yao 
43891b1f57cfSRiccardo Mancini 	zstd_fini(&(session->zstd_data));
439053f5e908SArnaldo Carvalho de Melo 	evlist__free_stats(session->evlist);
4391133dc4c3SIngo Molnar 	perf_session__delete(session);
4392faf3ac30SRiccardo Mancini 	perf_script__exit(&script);
43936cc870f0SNamhyung Kim 
43946cc870f0SNamhyung Kim 	if (script_started)
4395133dc4c3SIngo Molnar 		cleanup_scripting();
4396291961fcSAdrian Hunter 	dlfilter__cleanup(dlfilter);
43973d032a25SAdrian Hunter 	free_dlarg();
4398133dc4c3SIngo Molnar out:
4399133dc4c3SIngo Molnar 	return err;
4400133dc4c3SIngo Molnar }
4401