builtin-script.c 115 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2 3
#include "builtin.h"

4
#include "util/counts.h"
5
#include "util/debug.h"
6
#include "util/dso.h"
7
#include <subcmd/exec-cmd.h>
8
#include "util/header.h"
9
#include <subcmd/parse-options.h>
10
#include "util/perf_regs.h"
11
#include "util/session.h"
12
#include "util/tool.h"
13
#include "util/map.h"
14
#include "util/srcline.h"
15 16
#include "util/symbol.h"
#include "util/thread.h"
Ingo Molnar's avatar
Ingo Molnar committed
17
#include "util/trace-event.h"
18
#include "util/env.h"
19 20
#include "util/evlist.h"
#include "util/evsel.h"
21
#include "util/evsel_fprintf.h"
22
#include "util/evswitch.h"
23
#include "util/sort.h"
24
#include "util/data.h"
25
#include "util/auxtrace.h"
26 27 28
#include "util/cpumap.h"
#include "util/thread_map.h"
#include "util/stat.h"
29
#include "util/color.h"
30
#include "util/string2.h"
31
#include "util/thread-stack.h"
32
#include "util/time-utils.h"
33
#include "util/path.h"
34
#include "util/event.h"
35
#include "ui/ui.h"
36
#include "print_binary.h"
37
#include "archinsn.h"
38
#include <linux/bitmap.h>
39
#include <linux/kernel.h>
40
#include <linux/stringify.h>
41
#include <linux/time64.h>
42
#include <linux/zalloc.h>
43
#include <sys/utsname.h>
44
#include "asm/bug.h"
45
#include "util/mem-events.h"
46
#include "util/dump-insn.h"
47
#include <dirent.h>
48
#include <errno.h>
49
#include <inttypes.h>
50
#include <signal.h>
51
#include <sys/param.h>
52 53
#include <sys/types.h>
#include <sys/stat.h>
54
#include <fcntl.h>
55
#include <unistd.h>
56
#include <subcmd/pager.h>
57
#include <perf/evlist.h>
58
#include <linux/err.h>
59
#include "util/dlfilter.h"
60
#include "util/record.h"
61
#include "util/util.h"
62
#include "util/cgroup.h"
63
#include "perf.h"
64

65
#include <linux/ctype.h>
66 67 68
#ifdef HAVE_LIBTRACEEVENT
#include <traceevent/event-parse.h>
#endif
69

Tom Zanussi's avatar
Tom Zanussi committed
70 71
static char const		*script_name;
static char const		*generate_script_lang;
72
static bool			reltime;
73
static bool			deltatime;
74
static u64			initial_time;
75
static u64			previous_time;
76
static bool			debug_mode;
77
static u64			last_timestamp;
78
static u64			nr_unordered;
79
static bool			no_callchain;
80
static bool			latency_format;
81
static bool			system_wide;
82
static bool			print_flags;
83 84
static const char		*cpu_list;
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
85
static struct perf_stat_config	stat_config;
86
static int			max_blocks;
87
static bool			native_arch;
88
static struct dlfilter		*dlfilter;
89 90
static int			dlargc;
static char			**dlargv;
Tom Zanussi's avatar
Tom Zanussi committed
91

92
unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
93

94
enum perf_output_field {
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
	PERF_OUTPUT_COMM            = 1ULL << 0,
	PERF_OUTPUT_TID             = 1ULL << 1,
	PERF_OUTPUT_PID             = 1ULL << 2,
	PERF_OUTPUT_TIME            = 1ULL << 3,
	PERF_OUTPUT_CPU             = 1ULL << 4,
	PERF_OUTPUT_EVNAME          = 1ULL << 5,
	PERF_OUTPUT_TRACE           = 1ULL << 6,
	PERF_OUTPUT_IP              = 1ULL << 7,
	PERF_OUTPUT_SYM             = 1ULL << 8,
	PERF_OUTPUT_DSO             = 1ULL << 9,
	PERF_OUTPUT_ADDR            = 1ULL << 10,
	PERF_OUTPUT_SYMOFFSET       = 1ULL << 11,
	PERF_OUTPUT_SRCLINE         = 1ULL << 12,
	PERF_OUTPUT_PERIOD          = 1ULL << 13,
	PERF_OUTPUT_IREGS	    = 1ULL << 14,
	PERF_OUTPUT_BRSTACK	    = 1ULL << 15,
	PERF_OUTPUT_BRSTACKSYM	    = 1ULL << 16,
	PERF_OUTPUT_DATA_SRC	    = 1ULL << 17,
	PERF_OUTPUT_WEIGHT	    = 1ULL << 18,
	PERF_OUTPUT_BPF_OUTPUT	    = 1ULL << 19,
	PERF_OUTPUT_CALLINDENT	    = 1ULL << 20,
	PERF_OUTPUT_INSN	    = 1ULL << 21,
	PERF_OUTPUT_INSNLEN	    = 1ULL << 22,
	PERF_OUTPUT_BRSTACKINSN	    = 1ULL << 23,
	PERF_OUTPUT_BRSTACKOFF	    = 1ULL << 24,
	PERF_OUTPUT_SYNTH           = 1ULL << 25,
	PERF_OUTPUT_PHYS_ADDR       = 1ULL << 26,
	PERF_OUTPUT_UREGS	    = 1ULL << 27,
	PERF_OUTPUT_METRIC	    = 1ULL << 28,
	PERF_OUTPUT_MISC            = 1ULL << 29,
	PERF_OUTPUT_SRCCODE	    = 1ULL << 30,
	PERF_OUTPUT_IPC             = 1ULL << 31,
127
	PERF_OUTPUT_TOD             = 1ULL << 32,
128
	PERF_OUTPUT_DATA_PAGE_SIZE  = 1ULL << 33,
129
	PERF_OUTPUT_CODE_PAGE_SIZE  = 1ULL << 34,
130
	PERF_OUTPUT_INS_LAT         = 1ULL << 35,
131
	PERF_OUTPUT_BRSTACKINSNLEN  = 1ULL << 36,
132 133
	PERF_OUTPUT_MACHINE_PID     = 1ULL << 37,
	PERF_OUTPUT_VCPU            = 1ULL << 38,
134
	PERF_OUTPUT_CGROUP          = 1ULL << 39,
135
	PERF_OUTPUT_RETIRE_LAT      = 1ULL << 40,
136
	PERF_OUTPUT_DSOFF           = 1ULL << 41,
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
};

struct perf_script {
	struct perf_tool	tool;
	struct perf_session	*session;
	bool			show_task_events;
	bool			show_mmap_events;
	bool			show_switch_events;
	bool			show_namespace_events;
	bool			show_lost_events;
	bool			show_round_events;
	bool			show_bpf_events;
	bool			show_cgroup_events;
	bool			show_text_poke_events;
	bool			allocated;
	bool			per_event_dump;
	bool			stitch_lbr;
	struct evswitch		evswitch;
	struct perf_cpu_map	*cpus;
	struct perf_thread_map *threads;
	int			name_width;
	const char              *time_str;
	struct perf_time_interval *ptime_range;
	int			range_size;
	int			range_num;
162 163 164 165 166 167 168 169 170 171 172 173 174
};

struct output_option {
	const char *str;
	enum perf_output_field field;
} all_output_options[] = {
	{.str = "comm",  .field = PERF_OUTPUT_COMM},
	{.str = "tid",   .field = PERF_OUTPUT_TID},
	{.str = "pid",   .field = PERF_OUTPUT_PID},
	{.str = "time",  .field = PERF_OUTPUT_TIME},
	{.str = "cpu",   .field = PERF_OUTPUT_CPU},
	{.str = "event", .field = PERF_OUTPUT_EVNAME},
	{.str = "trace", .field = PERF_OUTPUT_TRACE},
175
	{.str = "ip",    .field = PERF_OUTPUT_IP},
176
	{.str = "sym",   .field = PERF_OUTPUT_SYM},
177
	{.str = "dso",   .field = PERF_OUTPUT_DSO},
178
	{.str = "dsoff", .field = PERF_OUTPUT_DSOFF},
179
	{.str = "addr",  .field = PERF_OUTPUT_ADDR},
180
	{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
181
	{.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
182
	{.str = "period", .field = PERF_OUTPUT_PERIOD},
183
	{.str = "iregs", .field = PERF_OUTPUT_IREGS},
184
	{.str = "uregs", .field = PERF_OUTPUT_UREGS},
185 186
	{.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
	{.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
187 188
	{.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},
	{.str = "weight",   .field = PERF_OUTPUT_WEIGHT},
189
	{.str = "bpf-output",   .field = PERF_OUTPUT_BPF_OUTPUT},
190
	{.str = "callindent", .field = PERF_OUTPUT_CALLINDENT},
191 192
	{.str = "insn", .field = PERF_OUTPUT_INSN},
	{.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},
193
	{.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
194
	{.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
195
	{.str = "synth", .field = PERF_OUTPUT_SYNTH},
196
	{.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
197
	{.str = "metric", .field = PERF_OUTPUT_METRIC},
198
	{.str = "misc", .field = PERF_OUTPUT_MISC},
199
	{.str = "srccode", .field = PERF_OUTPUT_SRCCODE},
200
	{.str = "ipc", .field = PERF_OUTPUT_IPC},
201
	{.str = "tod", .field = PERF_OUTPUT_TOD},
202
	{.str = "data_page_size", .field = PERF_OUTPUT_DATA_PAGE_SIZE},
203
	{.str = "code_page_size", .field = PERF_OUTPUT_CODE_PAGE_SIZE},
204
	{.str = "ins_lat", .field = PERF_OUTPUT_INS_LAT},
205
	{.str = "brstackinsnlen", .field = PERF_OUTPUT_BRSTACKINSNLEN},
206 207
	{.str = "machine_pid", .field = PERF_OUTPUT_MACHINE_PID},
	{.str = "vcpu", .field = PERF_OUTPUT_VCPU},
208
	{.str = "cgroup", .field = PERF_OUTPUT_CGROUP},
209
	{.str = "retire_lat", .field = PERF_OUTPUT_RETIRE_LAT},
210 211
};

212 213
enum {
	OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,
214
	OUTPUT_TYPE_OTHER,
215 216 217
	OUTPUT_TYPE_MAX
};

218
/* default set to maintain compatibility with current format */
219 220
static struct {
	bool user_set;
221
	bool wildcard_set;
222
	unsigned int print_ip_opts;
223 224
	u64 fields;
	u64 invalid_fields;
225
	u64 user_set_fields;
226
	u64 user_unset_fields;
227
} output[OUTPUT_TYPE_MAX] = {
228 229 230 231 232 233

	[PERF_TYPE_HARDWARE] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
234
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
235 236
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
237

238
		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
239 240 241 242 243 244 245
	},

	[PERF_TYPE_SOFTWARE] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
246
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
247 248 249
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
			      PERF_OUTPUT_BPF_OUTPUT,
250 251 252 253 254 255 256 257 258

		.invalid_fields = PERF_OUTPUT_TRACE,
	},

	[PERF_TYPE_TRACEPOINT] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
				  PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
259
				  PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE
260
	},
261

262 263 264 265 266 267 268 269 270 271 272 273
	[PERF_TYPE_HW_CACHE] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,

		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
	},

274 275 276 277 278
	[PERF_TYPE_RAW] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
279
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
280 281 282
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
			      PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC |
283
			      PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR |
284
			      PERF_OUTPUT_DATA_PAGE_SIZE | PERF_OUTPUT_CODE_PAGE_SIZE |
285
			      PERF_OUTPUT_INS_LAT | PERF_OUTPUT_RETIRE_LAT,
286

287
		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
288
	},
289 290 291 292 293 294 295

	[PERF_TYPE_BREAKPOINT] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
296 297
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
298

299
		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
300
	},
301 302 303 304 305 306 307

	[OUTPUT_TYPE_SYNTH] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
308 309
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_SYNTH,
310 311 312

		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
	},
313 314 315 316 317 318 319 320 321 322 323 324

	[OUTPUT_TYPE_OTHER] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,

		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
	},
325
};
326

327
struct evsel_script {
328 329 330
       char *filename;
       FILE *fp;
       u64  samples;
331 332 333
       /* For metric output */
       u64  val;
       int  gnum;
334 335
};

336
static inline struct evsel_script *evsel_script(struct evsel *evsel)
337
{
338
	return (struct evsel_script *)evsel->priv;
339 340
}

341
static struct evsel_script *evsel_script__new(struct evsel *evsel, struct perf_data *data)
342
{
343
	struct evsel_script *es = zalloc(sizeof(*es));
344 345

	if (es != NULL) {
346
		if (asprintf(&es->filename, "%s.%s.dump", data->file.path, evsel__name(evsel)) < 0)
347 348 349 350 351 352 353 354 355 356 357 358 359 360
			goto out_free;
		es->fp = fopen(es->filename, "w");
		if (es->fp == NULL)
			goto out_free_filename;
	}

	return es;
out_free_filename:
	zfree(&es->filename);
out_free:
	free(es);
	return NULL;
}

361
static void evsel_script__delete(struct evsel_script *es)
362 363 364 365 366 367 368
{
	zfree(&es->filename);
	fclose(es->fp);
	es->fp = NULL;
	free(es);
}

369
static int evsel_script__fprintf(struct evsel_script *es, FILE *fp)
370 371 372 373 374 375 376 377
{
	struct stat st;

	fstat(fileno(es->fp), &st);
	return fprintf(fp, "[ perf script: Wrote %.3f MB %s (%" PRIu64 " samples) ]\n",
		       st.st_size / 1024.0 / 1024.0, es->filename, es->samples);
}

378 379 380 381 382 383
static inline int output_type(unsigned int type)
{
	switch (type) {
	case PERF_TYPE_SYNTH:
		return OUTPUT_TYPE_SYNTH;
	default:
384 385
		if (type < PERF_TYPE_MAX)
			return type;
386
	}
387 388

	return OUTPUT_TYPE_OTHER;
389 390
}

391 392 393
static bool output_set_by_user(void)
{
	int j;
394
	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
395 396 397 398 399
		if (output[j].user_set)
			return true;
	}
	return false;
}
400

401 402 403 404 405 406 407 408 409 410 411 412 413 414
static const char *output_field2str(enum perf_output_field field)
{
	int i, imax = ARRAY_SIZE(all_output_options);
	const char *str = "";

	for (i = 0; i < imax; ++i) {
		if (all_output_options[i].field == field) {
			str = all_output_options[i].str;
			break;
		}
	}
	return str;
}

415
#define PRINT_FIELD(x)  (output[output_type(attr->type)].fields & PERF_OUTPUT_##x)
416

417 418
static int evsel__do_check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
				 enum perf_output_field field, bool allow_user_set)
419
{
420
	struct perf_event_attr *attr = &evsel->core.attr;
421
	int type = output_type(attr->type);
422 423 424 425 426
	const char *evname;

	if (attr->sample_type & sample_type)
		return 0;

427
	if (output[type].user_set_fields & field) {
428 429
		if (allow_user_set)
			return 0;
430
		evname = evsel__name(evsel);
431 432 433 434 435 436 437 438
		pr_err("Samples for '%s' event do not have %s attribute set. "
		       "Cannot print '%s' field.\n",
		       evname, sample_msg, output_field2str(field));
		return -1;
	}

	/* user did not ask for it explicitly so remove from the default list */
	output[type].fields &= ~field;
439
	evname = evsel__name(evsel);
440 441 442 443 444 445 446
	pr_debug("Samples for '%s' event do not have %s attribute set. "
		 "Skipping '%s' field.\n",
		 evname, sample_msg, output_field2str(field));

	return 0;
}

447 448
static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
			      enum perf_output_field field)
449
{
450
	return evsel__do_check_stype(evsel, sample_type, sample_msg, field, false);
451 452
}

453
static int evsel__check_attr(struct evsel *evsel, struct perf_session *session)
454
{
455
	struct perf_event_attr *attr = &evsel->core.attr;
456 457
	bool allow_user_set;

458 459 460
	if (evsel__is_dummy_event(evsel))
		return 0;

461 462 463
	if (perf_header__has_feat(&session->header, HEADER_STAT))
		return 0;

464 465
	allow_user_set = perf_header__has_feat(&session->header,
					       HEADER_AUXTRACE);
466

467
	if (PRINT_FIELD(TRACE) &&
468
	    !perf_session__has_traces(session, "record -R"))
469 470
		return -EINVAL;

471
	if (PRINT_FIELD(IP)) {
472
		if (evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", PERF_OUTPUT_IP))
473 474
			return -EINVAL;
	}
475 476

	if (PRINT_FIELD(ADDR) &&
477
	    evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", PERF_OUTPUT_ADDR, allow_user_set))
478 479
		return -EINVAL;

480
	if (PRINT_FIELD(DATA_SRC) &&
481
	    evsel__do_check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC", PERF_OUTPUT_DATA_SRC, allow_user_set))
482 483 484
		return -EINVAL;

	if (PRINT_FIELD(WEIGHT) &&
485
	    evsel__do_check_stype(evsel, PERF_SAMPLE_WEIGHT_TYPE, "WEIGHT", PERF_OUTPUT_WEIGHT, allow_user_set))
486 487
		return -EINVAL;

488
	if (PRINT_FIELD(SYM) &&
489
	    !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
490
		pr_err("Display of symbols requested but neither sample IP nor "
491
			   "sample address\navailable. Hence, no addresses to convert "
492
		       "to symbols.\n");
493 494
		return -EINVAL;
	}
495 496 497 498 499
	if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
		pr_err("Display of offsets requested but symbol is not"
		       "selected.\n");
		return -EINVAL;
	}
500
	if (PRINT_FIELD(DSO) &&
501
	    !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
502
		pr_err("Display of DSO requested but no address to convert.\n");
503 504
		return -EINVAL;
	}
505
	if ((PRINT_FIELD(SRCLINE) || PRINT_FIELD(SRCCODE)) && !PRINT_FIELD(IP)) {
506 507 508 509
		pr_err("Display of source line number requested but sample IP is not\n"
		       "selected. Hence, no address to lookup the source line number.\n");
		return -EINVAL;
	}
510
	if ((PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN)) && !allow_user_set &&
511
	    !(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY)) {
512 513 514 515
		pr_err("Display of branch stack assembler requested, but non all-branch filter set\n"
		       "Hint: run 'perf record -b ...'\n");
		return -EINVAL;
	}
516
	if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
517
	    evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", PERF_OUTPUT_TID|PERF_OUTPUT_PID))
518 519 520
		return -EINVAL;

	if (PRINT_FIELD(TIME) &&
521
	    evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", PERF_OUTPUT_TIME))
522 523 524
		return -EINVAL;

	if (PRINT_FIELD(CPU) &&
525
	    evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU", PERF_OUTPUT_CPU, allow_user_set))
526
		return -EINVAL;
527

528
	if (PRINT_FIELD(IREGS) &&
529
	    evsel__do_check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", PERF_OUTPUT_IREGS, allow_user_set))
530 531
		return -EINVAL;

532
	if (PRINT_FIELD(UREGS) &&
533
	    evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS", PERF_OUTPUT_UREGS))
534 535
		return -EINVAL;

536
	if (PRINT_FIELD(PHYS_ADDR) &&
537
	    evsel__do_check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", PERF_OUTPUT_PHYS_ADDR, allow_user_set))
538 539
		return -EINVAL;

540 541 542 543
	if (PRINT_FIELD(DATA_PAGE_SIZE) &&
	    evsel__check_stype(evsel, PERF_SAMPLE_DATA_PAGE_SIZE, "DATA_PAGE_SIZE", PERF_OUTPUT_DATA_PAGE_SIZE))
		return -EINVAL;

544 545 546 547
	if (PRINT_FIELD(CODE_PAGE_SIZE) &&
	    evsel__check_stype(evsel, PERF_SAMPLE_CODE_PAGE_SIZE, "CODE_PAGE_SIZE", PERF_OUTPUT_CODE_PAGE_SIZE))
		return -EINVAL;

548 549 550 551
	if (PRINT_FIELD(INS_LAT) &&
	    evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT_STRUCT, "WEIGHT_STRUCT", PERF_OUTPUT_INS_LAT))
		return -EINVAL;

552 553 554 555 556 557
	if (PRINT_FIELD(CGROUP) &&
	    evsel__check_stype(evsel, PERF_SAMPLE_CGROUP, "CGROUP", PERF_OUTPUT_CGROUP)) {
		pr_err("Hint: run 'perf record --all-cgroups ...'\n");
		return -EINVAL;
	}

558 559 560 561
	if (PRINT_FIELD(RETIRE_LAT) &&
	    evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT_STRUCT, "WEIGHT_STRUCT", PERF_OUTPUT_RETIRE_LAT))
		return -EINVAL;

562 563 564
	return 0;
}

565 566
static void set_print_ip_opts(struct perf_event_attr *attr)
{
567
	unsigned int type = output_type(attr->type);
568 569 570

	output[type].print_ip_opts = 0;
	if (PRINT_FIELD(IP))
571
		output[type].print_ip_opts |= EVSEL__PRINT_IP;
572 573

	if (PRINT_FIELD(SYM))
574
		output[type].print_ip_opts |= EVSEL__PRINT_SYM;
575 576

	if (PRINT_FIELD(DSO))
577
		output[type].print_ip_opts |= EVSEL__PRINT_DSO;
578

579 580 581
	if (PRINT_FIELD(DSOFF))
		output[type].print_ip_opts |= EVSEL__PRINT_DSOFF;

582
	if (PRINT_FIELD(SYMOFFSET))
583
		output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET;
584 585

	if (PRINT_FIELD(SRCLINE))
586
		output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
587 588
}

589 590 591 592 593 594
static struct evsel *find_first_output_type(struct evlist *evlist,
					    unsigned int type)
{
	struct evsel *evsel;

	evlist__for_each_entry(evlist, evsel) {
595 596
		if (evsel__is_dummy_event(evsel))
			continue;
597 598 599 600 601 602
		if (output_type(evsel->core.attr.type) == (int)type)
			return evsel;
	}
	return NULL;
}

603 604 605 606 607 608
/*
 * verify all user requested events exist and the samples
 * have the expected data
 */
static int perf_session__check_output_opt(struct perf_session *session)
{
609
	bool tod = false;
610
	unsigned int j;
611
	struct evsel *evsel;
612

613
	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
614
		evsel = find_first_output_type(session->evlist, j);
615 616 617 618 619

		/*
		 * even if fields is set to 0 (ie., show nothing) event must
		 * exist if user explicitly includes it on the command line
		 */
620 621
		if (!evsel && output[j].user_set && !output[j].wildcard_set &&
		    j != OUTPUT_TYPE_SYNTH) {
622
			pr_err("%s events do not exist. "
623
			       "Remove corresponding -F option to proceed.\n",
624 625 626 627 628
			       event_type(j));
			return -1;
		}

		if (evsel && output[j].fields &&
629
			evsel__check_attr(evsel, session))
630
			return -1;
631 632 633 634

		if (evsel == NULL)
			continue;

635 636 637 638
		/* 'dsoff' implys 'dso' field */
		if (output[j].fields & PERF_OUTPUT_DSOFF)
			output[j].fields |= PERF_OUTPUT_DSO;

639
		set_print_ip_opts(&evsel->core.attr);
640
		tod |= output[j].fields & PERF_OUTPUT_TOD;
641 642
	}

643 644
	if (!no_callchain) {
		bool use_callchain = false;
645
		bool not_pipe = false;
646

647
		evlist__for_each_entry(session->evlist, evsel) {
648
			not_pipe = true;
649
			if (evsel__has_callchain(evsel)) {
650 651 652 653
				use_callchain = true;
				break;
			}
		}
654
		if (not_pipe && !use_callchain)
655 656 657
			symbol_conf.use_callchain = false;
	}

658 659 660 661 662 663 664 665
	/*
	 * set default for tracepoints to print symbols only
	 * if callchains are present
	 */
	if (symbol_conf.use_callchain &&
	    !output[PERF_TYPE_TRACEPOINT].user_set) {
		j = PERF_TYPE_TRACEPOINT;

666
		evlist__for_each_entry(session->evlist, evsel) {
667
			if (evsel->core.attr.type != j)
668 669
				continue;

670
			if (evsel__has_callchain(evsel)) {
671 672
				output[j].fields |= PERF_OUTPUT_IP;
				output[j].fields |= PERF_OUTPUT_SYM;
673
				output[j].fields |= PERF_OUTPUT_SYMOFFSET;
674
				output[j].fields |= PERF_OUTPUT_DSO;
675
				set_print_ip_opts(&evsel->core.attr);
676 677
				goto out;
			}
678 679 680
		}
	}

681 682 683 684 685
	if (tod && !session->header.env.clock.enabled) {
		pr_err("Can't provide 'tod' time, missing clock data. "
		       "Please record with -k/--clockid option.\n");
		return -1;
	}
686
out:
687 688
	return 0;
}
689

690
static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, const char *arch,
691
				     FILE *fp)
692 693
{
	unsigned i = 0, r;
694
	int printed = 0;
695 696

	if (!regs || !regs->regs)
697
		return 0;
698

699
	printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi);
700 701 702

	for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
		u64 val = regs->regs[i++];
703
		printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r, arch), val);
704
	}
705 706

	return printed;
707 708
}

709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
#define DEFAULT_TOD_FMT "%F %H:%M:%S"

static char*
tod_scnprintf(struct perf_script *script, char *buf, int buflen,
	     u64 timestamp)
{
	u64 tod_ns, clockid_ns;
	struct perf_env *env;
	unsigned long nsec;
	struct tm ltime;
	char date[64];
	time_t sec;

	buf[0] = '\0';
	if (buflen < 64 || !script)
		return buf;

	env = &script->session->header.env;
	if (!env->clock.enabled) {
		scnprintf(buf, buflen, "disabled");
		return buf;
	}

	clockid_ns = env->clock.clockid_ns;
	tod_ns     = env->clock.tod_ns;

	if (timestamp > clockid_ns)
		tod_ns += timestamp - clockid_ns;
	else
		tod_ns -= clockid_ns - timestamp;

	sec  = (time_t) (tod_ns / NSEC_PER_SEC);
	nsec = tod_ns - sec * NSEC_PER_SEC;

	if (localtime_r(&sec, &ltime) == NULL) {
		scnprintf(buf, buflen, "failed");
	} else {
		strftime(date, sizeof(date), DEFAULT_TOD_FMT, &ltime);

		if (symbol_conf.nanosecs) {
			snprintf(buf, buflen, "%s.%09lu", date, nsec);
		} else {
			snprintf(buf, buflen, "%s.%06lu",
				 date, nsec / NSEC_PER_USEC);
		}
	}

	return buf;
}

759
static int perf_sample__fprintf_iregs(struct perf_sample *sample,
760
				      struct perf_event_attr *attr, const char *arch, FILE *fp)
761 762
{
	return perf_sample__fprintf_regs(&sample->intr_regs,
763
					 attr->sample_regs_intr, arch, fp);
764 765 766
}

static int perf_sample__fprintf_uregs(struct perf_sample *sample,
767
				      struct perf_event_attr *attr, const char *arch, FILE *fp)
768 769
{
	return perf_sample__fprintf_regs(&sample->user_regs,
770
					 attr->sample_regs_user, arch, fp);
771 772
}

773 774
static int perf_sample__fprintf_start(struct perf_script *script,
				      struct perf_sample *sample,
775
				      struct thread *thread,
776
				      struct evsel *evsel,
777
				      u32 type, FILE *fp)
778
{
779
	struct perf_event_attr *attr = &evsel->core.attr;
780
	unsigned long secs;
781
	unsigned long long nsecs;
782
	int printed = 0;
783
	char tstr[128];
784

785 786 787 788 789 790 791
	if (PRINT_FIELD(MACHINE_PID) && sample->machine_pid)
		printed += fprintf(fp, "VM:%5d ", sample->machine_pid);

	/* Print VCPU only for guest events i.e. with machine_pid */
	if (PRINT_FIELD(VCPU) && sample->machine_pid)
		printed += fprintf(fp, "VCPU:%03d ", sample->vcpu);

792
	if (PRINT_FIELD(COMM)) {
793 794
		const char *comm = thread ? thread__comm_str(thread) : ":-1";

795
		if (latency_format)
796
			printed += fprintf(fp, "%8.8s ", comm);
797
		else if (PRINT_FIELD(IP) && evsel__has_callchain(evsel) && symbol_conf.use_callchain)
798
			printed += fprintf(fp, "%s ", comm);
799
		else
800
			printed += fprintf(fp, "%16s ", comm);
801
	}
802

803
	if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
804
		printed += fprintf(fp, "%5d/%-5d ", sample->pid, sample->tid);
805
	else if (PRINT_FIELD(PID))
806
		printed += fprintf(fp, "%5d ", sample->pid);
807
	else if (PRINT_FIELD(TID))
808
		printed += fprintf(fp, "%5d ", sample->tid);
809 810 811

	if (PRINT_FIELD(CPU)) {
		if (latency_format)
812
			printed += fprintf(fp, "%3d ", sample->cpu);
813
		else
814
			printed += fprintf(fp, "[%03d] ", sample->cpu);
815
	}
816

817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845
	if (PRINT_FIELD(MISC)) {
		int ret = 0;

		#define has(m) \
			(sample->misc & PERF_RECORD_MISC_##m) == PERF_RECORD_MISC_##m

		if (has(KERNEL))
			ret += fprintf(fp, "K");
		if (has(USER))
			ret += fprintf(fp, "U");
		if (has(HYPERVISOR))
			ret += fprintf(fp, "H");
		if (has(GUEST_KERNEL))
			ret += fprintf(fp, "G");
		if (has(GUEST_USER))
			ret += fprintf(fp, "g");

		switch (type) {
		case PERF_RECORD_MMAP:
		case PERF_RECORD_MMAP2:
			if (has(MMAP_DATA))
				ret += fprintf(fp, "M");
			break;
		case PERF_RECORD_COMM:
			if (has(COMM_EXEC))
				ret += fprintf(fp, "E");
			break;
		case PERF_RECORD_SWITCH:
		case PERF_RECORD_SWITCH_CPU_WIDE:
846
			if (has(SWITCH_OUT)) {
847
				ret += fprintf(fp, "S");
848 849 850
				if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT)
					ret += fprintf(fp, "p");
			}
851 852 853 854 855 856 857 858 859 860
		default:
			break;
		}

		#undef has

		ret += fprintf(fp, "%*s", 6 - ret, " ");
		printed += ret;
	}

861 862 863 864 865
	if (PRINT_FIELD(TOD)) {
		tod_scnprintf(script, tstr, sizeof(tstr), sample->time);
		printed += fprintf(fp, "%s ", tstr);
	}

866
	if (PRINT_FIELD(TIME)) {
867 868 869 870 871
		u64 t = sample->time;
		if (reltime) {
			if (!initial_time)
				initial_time = sample->time;
			t = sample->time - initial_time;
872 873 874 875 876 877 878
		} else if (deltatime) {
			if (previous_time)
				t = sample->time - previous_time;
			else {
				t = 0;
			}
			previous_time = sample->time;
879 880
		}
		nsecs = t;
881 882
		secs = nsecs / NSEC_PER_SEC;
		nsecs -= secs * NSEC_PER_SEC;
883

884
		if (symbol_conf.nanosecs)
885
			printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs);
886 887
		else {
			char sample_time[32];
888
			timestamp__scnprintf_usec(t, sample_time, sizeof(sample_time));
889
			printed += fprintf(fp, "%12s: ", sample_time);
890
		}
891
	}
892 893

	return printed;
894 895
}

896 897 898 899 900 901 902 903 904
static inline char
mispred_str(struct branch_entry *br)
{
	if (!(br->flags.mispred  || br->flags.predicted))
		return '-';

	return br->flags.predicted ? 'P' : 'M';
}

905 906
static int print_bstack_flags(FILE *fp, struct branch_entry *br)
{
907
	return fprintf(fp, "/%c/%c/%c/%d/%s/%s ",
908 909 910
		       mispred_str(br),
		       br->flags.in_tx ? 'X' : '-',
		       br->flags.abort ? 'A' : '-',
911
		       br->flags.cycles,
912 913
		       get_branch_type(br),
		       br->flags.spec ? branch_spec_desc(br->flags.spec) : "-");
914 915
}

916 917 918
static int perf_sample__fprintf_brstack(struct perf_sample *sample,
					struct thread *thread,
					struct perf_event_attr *attr, FILE *fp)
919 920
{
	struct branch_stack *br = sample->branch_stack;
921
	struct branch_entry *entries = perf_sample__branch_entries(sample);
922 923
	struct addr_location alf, alt;
	u64 i, from, to;
924
	int printed = 0;
925 926

	if (!(br && br->nr))
927
		return 0;
928 929

	for (i = 0; i < br->nr; i++) {
930 931
		from = entries[i].from;
		to   = entries[i].to;
932 933 934 935

		if (PRINT_FIELD(DSO)) {
			memset(&alf, 0, sizeof(alf));
			memset(&alt, 0, sizeof(alt));
936 937
			thread__find_map_fb(thread, sample->cpumode, from, &alf);
			thread__find_map_fb(thread, sample->cpumode, to, &alt);
938 939
		}

940
		printed += fprintf(fp, " 0x%"PRIx64, from);
941 942
		if (PRINT_FIELD(DSO))
			printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);
943

944
		printed += fprintf(fp, "/0x%"PRIx64, to);
945 946
		if (PRINT_FIELD(DSO))
			printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);
947

948
		printed += print_bstack_flags(fp, entries + i);
949
	}
950 951

	return printed;
952 953
}

954 955 956
static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
					   struct thread *thread,
					   struct perf_event_attr *attr, FILE *fp)
957 958
{
	struct branch_stack *br = sample->branch_stack;
959
	struct branch_entry *entries = perf_sample__branch_entries(sample);
960 961
	struct addr_location alf, alt;
	u64 i, from, to;
962
	int printed = 0;
963 964

	if (!(br && br->nr))
965
		return 0;
966 967 968 969 970

	for (i = 0; i < br->nr; i++) {

		memset(&alf, 0, sizeof(alf));
		memset(&alt, 0, sizeof(alt));
971 972
		from = entries[i].from;
		to   = entries[i].to;
973

974 975
		thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
		thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
976

977
		printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
978 979
		if (PRINT_FIELD(DSO))
			printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);
980 981
		printed += fprintf(fp, "%c", '/');
		printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp);
982 983
		if (PRINT_FIELD(DSO))
			printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);
984
		printed += print_bstack_flags(fp, entries + i);
985
	}
986 987

	return printed;
988 989
}

990 991 992
static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
					   struct thread *thread,
					   struct perf_event_attr *attr, FILE *fp)
993 994
{
	struct branch_stack *br = sample->branch_stack;
995
	struct branch_entry *entries = perf_sample__branch_entries(sample);
996 997
	struct addr_location alf, alt;
	u64 i, from, to;
998
	int printed = 0;
999 1000

	if (!(br && br->nr))
1001
		return 0;
1002 1003 1004 1005 1006

	for (i = 0; i < br->nr; i++) {

		memset(&alf, 0, sizeof(alf));
		memset(&alt, 0, sizeof(alt));
1007 1008
		from = entries[i].from;
		to   = entries[i].to;
1009

1010
		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
1011
		    !map__dso(alf.map)->adjust_symbols)
1012
			from = map__dso_map_ip(alf.map, from);
1013

1014
		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
1015
		    !map__dso(alt.map)->adjust_symbols)
1016
			to = map__dso_map_ip(alt.map, to);
1017

1018
		printed += fprintf(fp, " 0x%"PRIx64, from);
1019 1020
		if (PRINT_FIELD(DSO))
			printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);
1021
		printed += fprintf(fp, "/0x%"PRIx64, to);
1022 1023
		if (PRINT_FIELD(DSO))
			printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);
1024
		printed += print_bstack_flags(fp, entries + i);
1025
	}
1026 1027

	return printed;
1028
}
1029 1030 1031 1032 1033 1034 1035 1036 1037
#define MAXBB 16384UL

static int grab_bb(u8 *buffer, u64 start, u64 end,
		    struct machine *machine, struct thread *thread,
		    bool *is64bit, u8 *cpumode, bool last)
{
	long offset, len;
	struct addr_location al;
	bool kernel;
1038
	struct dso *dso;
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055

	if (!start || !end)
		return 0;

	kernel = machine__kernel_ip(machine, start);
	if (kernel)
		*cpumode = PERF_RECORD_MISC_KERNEL;
	else
		*cpumode = PERF_RECORD_MISC_USER;

	/*
	 * Block overlaps between kernel and user.
	 * This can happen due to ring filtering
	 * On Intel CPUs the entry into the kernel is filtered,
	 * but the exit is not. Let the caller patch it up.
	 */
	if (kernel != machine__kernel_ip(machine, end)) {
1056
		pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end);
1057 1058 1059 1060 1061 1062
		return -ENXIO;
	}

	memset(&al, 0, sizeof(al));
	if (end - start > MAXBB - MAXINSN) {
		if (last)
1063
			pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end);
1064
		else
1065
			pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start);
1066 1067 1068
		return 0;
	}

1069
	if (!thread__find_map(thread, *cpumode, start, &al) || (dso = map__dso(al.map)) == NULL) {
1070
		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
1071 1072
		return 0;
	}
1073
	if (dso->data.status == DSO_DATA_STATUS_ERROR) {
1074
		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
1075 1076 1077 1078 1079 1080
		return 0;
	}

	/* Load maps to ensure dso->is_64_bit has been updated */
	map__load(al.map);

1081
	offset = map__map_ip(al.map, start);
1082
	len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer,
1083 1084
				    end - start + MAXINSN);

1085
	*is64bit = dso->is_64_bit;
1086
	if (len <= 0)
1087
		pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
1088 1089 1090 1091
			start, end);
	return len;
}

1092 1093 1094 1095 1096 1097 1098
static int map__fprintf_srccode(struct map *map, u64 addr, FILE *fp, struct srccode_state *state)
{
	char *srcfile;
	int ret = 0;
	unsigned line;
	int len;
	char *srccode;
1099
	struct dso *dso;
1100

1101
	if (!map || (dso = map__dso(map)) == NULL)
1102
		return 0;
1103
	srcfile = get_srcline_split(dso,
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
				    map__rip_2objdump(map, addr),
				    &line);
	if (!srcfile)
		return 0;

	/* Avoid redundant printing */
	if (state &&
	    state->srcfile &&
	    !strcmp(state->srcfile, srcfile) &&
	    state->line == line) {
		free(srcfile);
		return 0;
	}

	srccode = find_sourceline(srcfile, line, &len);
	if (!srccode)
		goto out_free_line;

	ret = fprintf(fp, "|%-8d %.*s", line, len, srccode);

	if (state) {
		state->srcfile = srcfile;
		state->line = line;
	}
	return ret;

out_free_line:
	free(srcfile);
	return ret;
}

1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150
static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr)
{
	struct addr_location al;
	int ret = 0;

	memset(&al, 0, sizeof(al));
	thread__find_map(thread, cpumode, addr, &al);
	if (!al.map)
		return 0;
	ret = map__fprintf_srccode(al.map, al.addr, stdout,
		    &thread->srccode_state);
	if (ret)
		ret += printf("\n");
	return ret;
}

1151 1152
static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
			    struct perf_insn *x, u8 *inbuf, int len,
1153 1154
			    int insn, FILE *fp, int *total_cycles,
			    struct perf_event_attr *attr)
1155
{
1156 1157 1158 1159 1160 1161 1162 1163
	int ilen = 0;
	int printed = fprintf(fp, "\t%016" PRIx64 "\t%-30s\t", ip,
			      dump_insn(x, ip, inbuf, len, &ilen));

	if (PRINT_FIELD(BRSTACKINSNLEN))
		printed += fprintf(fp, "ilen: %d\t", ilen);

	printed += fprintf(fp, "#%s%s%s%s",
1164 1165 1166 1167
			      en->flags.predicted ? " PRED" : "",
			      en->flags.mispred ? " MISPRED" : "",
			      en->flags.in_tx ? " INTX" : "",
			      en->flags.abort ? " ABORT" : "");
1168
	if (en->flags.cycles) {
1169 1170
		*total_cycles += en->flags.cycles;
		printed += fprintf(fp, " %d cycles [%d]", en->flags.cycles, *total_cycles);
1171
		if (insn)
1172
			printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
1173
	}
1174
	return printed + fprintf(fp, "\n");
1175 1176
}

1177 1178 1179
static int ip__fprintf_sym(uint64_t addr, struct thread *thread,
			   u8 cpumode, int cpu, struct symbol **lastsym,
			   struct perf_event_attr *attr, FILE *fp)
1180 1181
{
	struct addr_location al;
1182
	int off, printed = 0;
1183 1184 1185

	memset(&al, 0, sizeof(al));

1186 1187
	thread__find_map(thread, cpumode, addr, &al);

1188
	if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
1189
		return 0;
1190 1191 1192 1193 1194 1195 1196

	al.cpu = cpu;
	al.sym = NULL;
	if (al.map)
		al.sym = map__find_symbol(al.map, al.addr);

	if (!al.sym)
1197
		return 0;
1198 1199 1200 1201

	if (al.addr < al.sym->end)
		off = al.addr - al.sym->start;
	else
1202
		off = al.addr - map__start(al.map) - al.sym->start;
1203
	printed += fprintf(fp, "\t%s", al.sym->name);
1204
	if (off)
1205 1206
		printed += fprintf(fp, "%+d", off);
	printed += fprintf(fp, ":");
1207
	if (PRINT_FIELD(SRCLINE))
1208 1209
		printed += map__fprintf_srcline(al.map, al.addr, "\t", fp);
	printed += fprintf(fp, "\n");
1210
	*lastsym = al.sym;
1211 1212

	return printed;
1213 1214
}

1215 1216 1217 1218
static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
					    struct thread *thread,
					    struct perf_event_attr *attr,
					    struct machine *machine, FILE *fp)
1219 1220
{
	struct branch_stack *br = sample->branch_stack;
1221
	struct branch_entry *entries = perf_sample__branch_entries(sample);
1222
	u64 start, end;
1223
	int i, insn, len, nr, ilen, printed = 0;
1224 1225 1226 1227
	struct perf_insn x;
	u8 buffer[MAXBB];
	unsigned off;
	struct symbol *lastsym = NULL;
1228
	int total_cycles = 0;
1229 1230

	if (!(br && br->nr))
1231
		return 0;
1232 1233 1234 1235 1236 1237 1238
	nr = br->nr;
	if (max_blocks && nr > max_blocks + 1)
		nr = max_blocks + 1;

	x.thread = thread;
	x.cpu = sample->cpu;

1239
	printed += fprintf(fp, "%c", '\n');
1240 1241

	/* Handle first from jump, of which we don't know the entry. */
1242 1243
	len = grab_bb(buffer, entries[nr-1].from,
			entries[nr-1].from,
1244 1245
			machine, thread, &x.is64bit, &x.cpumode, false);
	if (len > 0) {
1246
		printed += ip__fprintf_sym(entries[nr - 1].from, thread,
1247
					   x.cpumode, x.cpu, &lastsym, attr, fp);
1248
		printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1],
1249 1250
					    &x, buffer, len, 0, fp, &total_cycles,
					    attr);
1251
		if (PRINT_FIELD(SRCCODE))
1252
			printed += print_srccode(thread, x.cpumode, entries[nr - 1].from);
1253 1254 1255 1256
	}

	/* Print all blocks */
	for (i = nr - 2; i >= 0; i--) {
1257
		if (entries[i].from || entries[i].to)
1258
			pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i,
1259 1260 1261 1262
				 entries[i].from,
				 entries[i].to);
		start = entries[i + 1].to;
		end   = entries[i].from;
1263 1264 1265 1266

		len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
		/* Patch up missing kernel transfers due to ring filters */
		if (len == -ENXIO && i > 0) {
1267
			end = entries[--i].from;
1268 1269 1270 1271 1272 1273 1274
			pr_debug("\tpatching up to %" PRIx64 "-%" PRIx64 "\n", start, end);
			len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
		}
		if (len <= 0)
			continue;

		insn = 0;
1275
		for (off = 0; off < (unsigned)len; off += ilen) {
1276 1277
			uint64_t ip = start + off;

1278
			printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
1279
			if (ip == end) {
1280
				printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp,
1281
							    &total_cycles, attr);
1282 1283
				if (PRINT_FIELD(SRCCODE))
					printed += print_srccode(thread, x.cpumode, ip);
1284 1285
				break;
			} else {
1286
				ilen = 0;
1287
				printed += fprintf(fp, "\t%016" PRIx64 "\t%s", ip,
1288
						   dump_insn(&x, ip, buffer + off, len - off, &ilen));
1289 1290 1291
				if (PRINT_FIELD(BRSTACKINSNLEN))
					printed += fprintf(fp, "\tilen: %d", ilen);
				printed += fprintf(fp, "\n");
1292 1293
				if (ilen == 0)
					break;
1294 1295
				if (PRINT_FIELD(SRCCODE))
					print_srccode(thread, x.cpumode, ip);
1296 1297 1298
				insn++;
			}
		}
1299
		if (off != end - start)
1300
			printed += fprintf(fp, "\tmismatch of LBR data and executable\n");
1301 1302 1303 1304 1305 1306
	}

	/*
	 * Hit the branch? In this case we are already done, and the target
	 * has not been executed yet.
	 */
1307
	if (entries[0].from == sample->ip)
1308
		goto out;
1309
	if (entries[0].flags.abort)
1310
		goto out;
1311 1312

	/*
1313
	 * Print final block up to sample
1314 1315 1316 1317 1318
	 *
	 * Due to pipeline delays the LBRs might be missing a branch
	 * or two, which can result in very large or negative blocks
	 * between final branch and sample. When this happens just
	 * continue walking after the last TO until we hit a branch.
1319
	 */
1320
	start = entries[0].to;
1321
	end = sample->ip;
1322 1323 1324 1325
	if (end < start) {
		/* Missing jump. Scan 128 bytes for the next branch */
		end = start + 128;
	}
1326
	len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
1327
	printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
1328 1329 1330 1331 1332
	if (len <= 0) {
		/* Print at least last IP if basic block did not work */
		len = grab_bb(buffer, sample->ip, sample->ip,
			      machine, thread, &x.is64bit, &x.cpumode, false);
		if (len <= 0)
1333
			goto out;
1334 1335 1336 1337 1338 1339
		ilen = 0;
		printed += fprintf(fp, "\t%016" PRIx64 "\t%s", sample->ip,
			dump_insn(&x, sample->ip, buffer, len, &ilen));
		if (PRINT_FIELD(BRSTACKINSNLEN))
			printed += fprintf(fp, "\tilen: %d", ilen);
		printed += fprintf(fp, "\n");
1340 1341
		if (PRINT_FIELD(SRCCODE))
			print_srccode(thread, x.cpumode, sample->ip);
1342
		goto out;
1343 1344
	}
	for (off = 0; off <= end - start; off += ilen) {
1345
		ilen = 0;
1346
		printed += fprintf(fp, "\t%016" PRIx64 "\t%s", start + off,
1347
				   dump_insn(&x, start + off, buffer + off, len - off, &ilen));
1348 1349 1350
		if (PRINT_FIELD(BRSTACKINSNLEN))
			printed += fprintf(fp, "\tilen: %d", ilen);
		printed += fprintf(fp, "\n");
1351 1352
		if (ilen == 0)
			break;
1353 1354 1355 1356 1357 1358 1359
		if (arch_is_branch(buffer + off, len - off, x.is64bit) && start + off != sample->ip) {
			/*
			 * Hit a missing branch. Just stop.
			 */
			printed += fprintf(fp, "\t... not reaching sample ...\n");
			break;
		}
1360 1361
		if (PRINT_FIELD(SRCCODE))
			print_srccode(thread, x.cpumode, start + off);
1362
	}
1363 1364
out:
	return printed;
1365
}
1366

1367 1368 1369
static int perf_sample__fprintf_addr(struct perf_sample *sample,
				     struct thread *thread,
				     struct perf_event_attr *attr, FILE *fp)
1370 1371
{
	struct addr_location al;
1372
	int printed = fprintf(fp, "%16" PRIx64, sample->addr);
1373 1374

	if (!sample_addr_correlates_sym(attr))
1375
		goto out;
1376

1377
	thread__resolve(thread, &al, sample);
1378 1379

	if (PRINT_FIELD(SYM)) {
1380
		printed += fprintf(fp, " ");
1381
		if (PRINT_FIELD(SYMOFFSET))
1382
			printed += symbol__fprintf_symname_offs(al.sym, &al, fp);
1383
		else
1384
			printed += symbol__fprintf_symname(al.sym, fp);
1385 1386
	}

1387 1388
	if (PRINT_FIELD(DSO))
		printed += map__fprintf_dsoname_dsoff(al.map, PRINT_FIELD(DSOFF), al.addr, fp);
1389 1390
out:
	return printed;
1391 1392
}

1393
static const char *resolve_branch_sym(struct perf_sample *sample,
1394
				      struct evsel *evsel,
1395 1396
				      struct thread *thread,
				      struct addr_location *al,
1397
				      struct addr_location *addr_al,
1398 1399
				      u64 *ip)
{
1400
	struct perf_event_attr *attr = &evsel->core.attr;
1401 1402 1403 1404
	const char *name = NULL;

	if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) {
		if (sample_addr_correlates_sym(attr)) {
1405 1406 1407 1408
			if (!addr_al->thread)
				thread__resolve(thread, addr_al, sample);
			if (addr_al->sym)
				name = addr_al->sym->name;
1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422
			else
				*ip = sample->addr;
		} else {
			*ip = sample->addr;
		}
	} else if (sample->flags & (PERF_IP_FLAG_RETURN | PERF_IP_FLAG_TRACE_END)) {
		if (al->sym)
			name = al->sym->name;
		else
			*ip = sample->ip;
	}
	return name;
}

1423
static int perf_sample__fprintf_callindent(struct perf_sample *sample,
1424
					   struct evsel *evsel,
1425
					   struct thread *thread,
1426 1427 1428
					   struct addr_location *al,
					   struct addr_location *addr_al,
					   FILE *fp)
1429
{
1430
	struct perf_event_attr *attr = &evsel->core.attr;
1431
	size_t depth = thread_stack__depth(thread, sample->cpu);
1432 1433 1434
	const char *name = NULL;
	static int spacing;
	int len = 0;
1435
	int dlen = 0;
1436 1437 1438 1439 1440 1441 1442 1443 1444
	u64 ip = 0;

	/*
	 * The 'return' has already been popped off the stack so the depth has
	 * to be adjusted to match the 'call'.
	 */
	if (thread->ts && sample->flags & PERF_IP_FLAG_RETURN)
		depth += 1;

1445
	name = resolve_branch_sym(sample, evsel, thread, al, addr_al, &ip);
1446

1447 1448 1449 1450 1451 1452
	if (PRINT_FIELD(DSO) && !(PRINT_FIELD(IP) || PRINT_FIELD(ADDR))) {
		dlen += fprintf(fp, "(");
		dlen += map__fprintf_dsoname(al->map, fp);
		dlen += fprintf(fp, ")\t");
	}

1453
	if (name)
1454
		len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);
1455
	else if (ip)
1456
		len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip);
1457 1458

	if (len < 0)
1459
		return len;
1460 1461 1462 1463 1464 1465 1466 1467 1468

	/*
	 * Try to keep the output length from changing frequently so that the
	 * output lines up more nicely.
	 */
	if (len > spacing || (len && len < spacing - 52))
		spacing = round_up(len + 4, 32);

	if (len < spacing)
1469 1470
		len += fprintf(fp, "%*s", spacing - len, "");

1471
	return len + dlen;
1472 1473
}

1474 1475 1476 1477 1478 1479
__weak void arch_fetch_insn(struct perf_sample *sample __maybe_unused,
			    struct thread *thread __maybe_unused,
			    struct machine *machine __maybe_unused)
{
}

1480 1481 1482 1483 1484 1485 1486
void script_fetch_insn(struct perf_sample *sample, struct thread *thread,
		       struct machine *machine)
{
	if (sample->insn_len == 0 && native_arch)
		arch_fetch_insn(sample, thread, machine);
}

1487 1488 1489 1490
static int perf_sample__fprintf_insn(struct perf_sample *sample,
				     struct perf_event_attr *attr,
				     struct thread *thread,
				     struct machine *machine, FILE *fp)
1491
{
1492 1493
	int printed = 0;

1494
	script_fetch_insn(sample, thread, machine);
1495

1496
	if (PRINT_FIELD(INSNLEN))
1497
		printed += fprintf(fp, " ilen: %d", sample->insn_len);
1498
	if (PRINT_FIELD(INSN) && sample->insn_len) {
1499 1500
		int i;

1501
		printed += fprintf(fp, " insn:");
1502
		for (i = 0; i < sample->insn_len; i++)
1503
			printed += fprintf(fp, " %02x", (unsigned char)sample->insn[i]);
1504
	}
1505
	if (PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN))
1506 1507 1508
		printed += perf_sample__fprintf_brstackinsn(sample, thread, attr, machine, fp);

	return printed;
1509 1510
}

1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524
static int perf_sample__fprintf_ipc(struct perf_sample *sample,
				    struct perf_event_attr *attr, FILE *fp)
{
	unsigned int ipc;

	if (!PRINT_FIELD(IPC) || !sample->cyc_cnt || !sample->insn_cnt)
		return 0;

	ipc = (sample->insn_cnt * 100) / sample->cyc_cnt;

	return fprintf(fp, " \t IPC: %u.%02u (%" PRIu64 "/%" PRIu64 ") ",
		       ipc / 100, ipc % 100, sample->insn_cnt, sample->cyc_cnt);
}

1525
static int perf_sample__fprintf_bts(struct perf_sample *sample,
1526
				    struct evsel *evsel,
1527 1528
				    struct thread *thread,
				    struct addr_location *al,
1529
				    struct addr_location *addr_al,
1530
				    struct machine *machine, FILE *fp)
1531
{
1532
	struct perf_event_attr *attr = &evsel->core.attr;
1533
	unsigned int type = output_type(attr->type);
1534
	bool print_srcline_last = false;
1535
	int printed = 0;
1536

1537
	if (PRINT_FIELD(CALLINDENT))
1538
		printed += perf_sample__fprintf_callindent(sample, evsel, thread, al, addr_al, fp);
1539

1540 1541
	/* print branch_from information */
	if (PRINT_FIELD(IP)) {
1542
		unsigned int print_opts = output[type].print_ip_opts;
1543
		struct callchain_cursor *cursor = NULL;
1544

1545
		if (symbol_conf.use_callchain && sample->callchain &&
1546
		    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
1547
					      sample, NULL, NULL, scripting_max_stack) == 0)
1548
			cursor = &callchain_cursor;
1549 1550

		if (cursor == NULL) {
1551
			printed += fprintf(fp, " ");
1552
			if (print_opts & EVSEL__PRINT_SRCLINE) {
1553
				print_srcline_last = true;
1554
				print_opts &= ~EVSEL__PRINT_SRCLINE;
1555
			}
1556
		} else
1557
			printed += fprintf(fp, "\n");
1558

1559 1560
		printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor,
					       symbol_conf.bt_stop_list, fp);
1561 1562 1563
	}

	/* print branch_to information */
1564
	if (PRINT_FIELD(ADDR) ||
1565
	    ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
1566
	     !output[type].user_set)) {
1567 1568
		printed += fprintf(fp, " => ");
		printed += perf_sample__fprintf_addr(sample, thread, attr, fp);
1569
	}
1570

1571 1572
	printed += perf_sample__fprintf_ipc(sample, attr, fp);

1573
	if (print_srcline_last)
1574
		printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
1575

1576
	printed += perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
1577 1578 1579 1580 1581 1582 1583 1584 1585 1586
	printed += fprintf(fp, "\n");
	if (PRINT_FIELD(SRCCODE)) {
		int ret = map__fprintf_srccode(al->map, al->addr, stdout,
					 &thread->srccode_state);
		if (ret) {
			printed += ret;
			printed += printf("\n");
		}
	}
	return printed;
1587 1588
}

1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605
static struct {
	u32 flags;
	const char *name;
} sample_flags[] = {
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"},
	{PERF_IP_FLAG_BRANCH, "jmp"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |	PERF_IP_FLAG_INTERRUPT, "hw int"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"},
1606 1607
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMENTRY, "vmentry"},
	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMEXIT, "vmexit"},
1608 1609 1610
	{0, NULL}
};

1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622
static const char *sample_flags_to_name(u32 flags)
{
	int i;

	for (i = 0; sample_flags[i].name ; i++) {
		if (sample_flags[i].flags == flags)
			return sample_flags[i].name;
	}

	return NULL;
}

1623
int perf_sample__sprintf_flags(u32 flags, char *str, size_t sz)
1624
{
1625 1626
	u32 xf = PERF_IP_FLAG_IN_TX | PERF_IP_FLAG_INTR_DISABLE |
		 PERF_IP_FLAG_INTR_TOGGLE;
1627
	const char *chars = PERF_IP_FLAG_CHARS;
1628
	const size_t n = strlen(PERF_IP_FLAG_CHARS);
1629
	const char *name = NULL;
1630
	size_t i, pos = 0;
1631
	char xs[16] = {0};
1632

1633 1634 1635 1636 1637 1638 1639
	if (flags & xf)
		snprintf(xs, sizeof(xs), "(%s%s%s)",
			 flags & PERF_IP_FLAG_IN_TX ? "x" : "",
			 flags & PERF_IP_FLAG_INTR_DISABLE ? "D" : "",
			 flags & PERF_IP_FLAG_INTR_TOGGLE ? "t" : "");

	name = sample_flags_to_name(flags & ~xf);
1640
	if (name)
1641
		return snprintf(str, sz, "%-15s%6s", name, xs);
1642 1643

	if (flags & PERF_IP_FLAG_TRACE_BEGIN) {
1644
		name = sample_flags_to_name(flags & ~(xf | PERF_IP_FLAG_TRACE_BEGIN));
1645
		if (name)
1646
			return snprintf(str, sz, "tr strt %-7s%6s", name, xs);
1647 1648 1649
	}

	if (flags & PERF_IP_FLAG_TRACE_END) {
1650
		name = sample_flags_to_name(flags & ~(xf | PERF_IP_FLAG_TRACE_END));
1651
		if (name)
1652
			return snprintf(str, sz, "tr end  %-7s%6s", name, xs);
1653 1654
	}

1655
	for (i = 0; i < n; i++, flags >>= 1) {
1656
		if ((flags & 1) && pos < sz)
1657 1658 1659
			str[pos++] = chars[i];
	}
	for (; i < 32; i++, flags >>= 1) {
1660
		if ((flags & 1) && pos < sz)
1661 1662
			str[pos++] = '?';
	}
1663 1664 1665 1666 1667 1668 1669 1670 1671
	if (pos < sz)
		str[pos] = 0;

	return pos;
}

static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
{
	char str[SAMPLE_FLAGS_BUF_SIZE];
1672

1673
	perf_sample__sprintf_flags(flags, str, sizeof(str));
1674
	return fprintf(fp, "  %-21s ", str);
1675 1676
}

1677 1678 1679 1680 1681 1682
struct printer_data {
	int line_no;
	bool hit_nul;
	bool is_printable;
};

1683 1684 1685
static int sample__fprintf_bpf_output(enum binary_printer_ops op,
				      unsigned int val,
				      void *extra, FILE *fp)
1686 1687 1688
{
	unsigned char ch = (unsigned char)val;
	struct printer_data *printer_data = extra;
1689
	int printed = 0;
1690 1691 1692

	switch (op) {
	case BINARY_PRINT_DATA_BEGIN:
1693
		printed += fprintf(fp, "\n");
1694 1695
		break;
	case BINARY_PRINT_LINE_BEGIN:
1696
		printed += fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" :
1697 1698 1699
						        "           ");
		break;
	case BINARY_PRINT_ADDR:
1700
		printed += fprintf(fp, " %04x:", val);
1701 1702
		break;
	case BINARY_PRINT_NUM_DATA:
1703
		printed += fprintf(fp, " %02x", val);
1704 1705
		break;
	case BINARY_PRINT_NUM_PAD:
1706
		printed += fprintf(fp, "   ");
1707 1708
		break;
	case BINARY_PRINT_SEP:
1709
		printed += fprintf(fp, "  ");
1710 1711 1712 1713 1714 1715
		break;
	case BINARY_PRINT_CHAR_DATA:
		if (printer_data->hit_nul && ch)
			printer_data->is_printable = false;

		if (!isprint(ch)) {
1716
			printed += fprintf(fp, "%c", '.');
1717 1718 1719 1720 1721 1722 1723 1724 1725

			if (!printer_data->is_printable)
				break;

			if (ch == '\0')
				printer_data->hit_nul = true;
			else
				printer_data->is_printable = false;
		} else {
1726
			printed += fprintf(fp, "%c", ch);
1727 1728 1729
		}
		break;
	case BINARY_PRINT_CHAR_PAD:
1730
		printed += fprintf(fp, " ");
1731 1732
		break;
	case BINARY_PRINT_LINE_END:
1733
		printed += fprintf(fp, "\n");
1734 1735 1736 1737 1738 1739
		printer_data->line_no++;
		break;
	case BINARY_PRINT_DATA_END:
	default:
		break;
	}
1740 1741

	return printed;
1742 1743
}

1744
static int perf_sample__fprintf_bpf_output(struct perf_sample *sample, FILE *fp)
1745 1746 1747
{
	unsigned int nr_bytes = sample->raw_size;
	struct printer_data printer_data = {0, false, true};
1748 1749
	int printed = binary__fprintf(sample->raw_data, nr_bytes, 8,
				      sample__fprintf_bpf_output, &printer_data, fp);
1750 1751

	if (printer_data.is_printable && printer_data.hit_nul)
1752 1753 1754
		printed += fprintf(fp, "%17s \"%s\"\n", "BPF string:", (char *)(sample->raw_data));

	return printed;
1755 1756
}

1757
static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp)
1758 1759
{
	if (len > 0 && len < spacing)
1760 1761 1762
		return fprintf(fp, "%*s", spacing - len, "");

	return 0;
1763 1764
}

1765
static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)
1766
{
1767
	return perf_sample__fprintf_spacing(len, 34, fp);
1768 1769
}

1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790
/* If a value contains only printable ASCII characters padded with NULLs */
static bool ptw_is_prt(u64 val)
{
	char c;
	u32 i;

	for (i = 0; i < sizeof(val); i++) {
		c = ((char *)&val)[i];
		if (!c)
			break;
		if (!isprint(c) || !isascii(c))
			return false;
	}
	for (; i < sizeof(val); i++) {
		c = ((char *)&val)[i];
		if (c)
			return false;
	}
	return true;
}

1791
static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp)
1792 1793
{
	struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
1794
	char str[sizeof(u64) + 1] = "";
1795
	int len;
1796
	u64 val;
1797 1798

	if (perf_sample__bad_synth_size(sample, *data))
1799
		return 0;
1800

1801 1802 1803 1804 1805 1806 1807
	val = le64_to_cpu(data->payload);
	if (ptw_is_prt(val)) {
		memcpy(str, &val, sizeof(val));
		str[sizeof(val)] = 0;
	}
	len = fprintf(fp, " IP: %u payload: %#" PRIx64 " %s ",
		      data->ip, val, str);
1808
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1809 1810
}

1811
static int perf_sample__fprintf_synth_mwait(struct perf_sample *sample, FILE *fp)
1812 1813 1814 1815 1816
{
	struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
	int len;

	if (perf_sample__bad_synth_size(sample, *data))
1817
		return 0;
1818

1819 1820 1821
	len = fprintf(fp, " hints: %#x extensions: %#x ",
		      data->hints, data->extensions);
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1822 1823
}

1824
static int perf_sample__fprintf_synth_pwre(struct perf_sample *sample, FILE *fp)
1825 1826 1827 1828 1829
{
	struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
	int len;

	if (perf_sample__bad_synth_size(sample, *data))
1830
		return 0;
1831

1832 1833 1834
	len = fprintf(fp, " hw: %u cstate: %u sub-cstate: %u ",
		      data->hw, data->cstate, data->subcstate);
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1835 1836
}

1837
static int perf_sample__fprintf_synth_exstop(struct perf_sample *sample, FILE *fp)
1838 1839 1840 1841 1842
{
	struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
	int len;

	if (perf_sample__bad_synth_size(sample, *data))
1843
		return 0;
1844

1845 1846
	len = fprintf(fp, " IP: %u ", data->ip);
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1847 1848
}

1849
static int perf_sample__fprintf_synth_pwrx(struct perf_sample *sample, FILE *fp)
1850 1851 1852 1853 1854
{
	struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
	int len;

	if (perf_sample__bad_synth_size(sample, *data))
1855
		return 0;
1856

1857
	len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ",
1858 1859
		     data->deepest_cstate, data->last_cstate,
		     data->wake_reason);
1860
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1861 1862
}

1863
static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp)
1864 1865 1866 1867 1868 1869
{
	struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample);
	unsigned int percent, freq;
	int len;

	if (perf_sample__bad_synth_size(sample, *data))
1870
		return 0;
1871 1872

	freq = (le32_to_cpu(data->freq) + 500) / 1000;
1873
	len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
1874 1875
	if (data->max_nonturbo) {
		percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
1876
		len += fprintf(fp, "(%3u%%) ", percent);
1877
	}
1878
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1879 1880
}

1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892
static int perf_sample__fprintf_synth_psb(struct perf_sample *sample, FILE *fp)
{
	struct perf_synth_intel_psb *data = perf_sample__synth_ptr(sample);
	int len;

	if (perf_sample__bad_synth_size(sample, *data))
		return 0;

	len = fprintf(fp, " psb offs: %#" PRIx64, data->offset);
	return len + perf_sample__fprintf_pt_spacing(len, fp);
}

1893 1894 1895 1896 1897 1898
/* Intel PT Event Trace */
static int perf_sample__fprintf_synth_evt(struct perf_sample *sample, FILE *fp)
{
	struct perf_synth_intel_evt *data = perf_sample__synth_ptr(sample);
	const char *cfe[32] = {NULL, "INTR", "IRET", "SMI", "RSM", "SIPI",
			       "INIT", "VMENTRY", "VMEXIT", "VMEXIT_INTR",
1899
			       "SHUTDOWN", NULL, "UINTR", "UIRET"};
1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929
	const char *evd[64] = {"PFA", "VMXQ", "VMXR"};
	const char *s;
	int len, i;

	if (perf_sample__bad_synth_size(sample, *data))
		return 0;

	s = cfe[data->type];
	if (s) {
		len = fprintf(fp, " cfe: %s IP: %d vector: %u",
			      s, data->ip, data->vector);
	} else {
		len = fprintf(fp, " cfe: %u IP: %d vector: %u",
			      data->type, data->ip, data->vector);
	}
	for (i = 0; i < data->evd_cnt; i++) {
		unsigned int et = data->evd[i].evd_type & 0x3f;

		s = evd[et];
		if (s) {
			len += fprintf(fp, " %s: %#" PRIx64,
				       s, data->evd[i].payload);
		} else {
			len += fprintf(fp, " EVD_%u: %#" PRIx64,
				       et, data->evd[i].payload);
		}
	}
	return len + perf_sample__fprintf_pt_spacing(len, fp);
}

1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942
static int perf_sample__fprintf_synth_iflag_chg(struct perf_sample *sample, FILE *fp)
{
	struct perf_synth_intel_iflag_chg *data = perf_sample__synth_ptr(sample);
	int len;

	if (perf_sample__bad_synth_size(sample, *data))
		return 0;

	len = fprintf(fp, " IFLAG: %d->%d %s branch", !data->iflag, data->iflag,
		      data->via_branch ? "via" : "non");
	return len + perf_sample__fprintf_pt_spacing(len, fp);
}

1943
static int perf_sample__fprintf_synth(struct perf_sample *sample,
1944
				      struct evsel *evsel, FILE *fp)
1945
{
1946
	switch (evsel->core.attr.config) {
1947
	case PERF_SYNTH_INTEL_PTWRITE:
1948
		return perf_sample__fprintf_synth_ptwrite(sample, fp);
1949
	case PERF_SYNTH_INTEL_MWAIT:
1950
		return perf_sample__fprintf_synth_mwait(sample, fp);
1951
	case PERF_SYNTH_INTEL_PWRE:
1952
		return perf_sample__fprintf_synth_pwre(sample, fp);
1953
	case PERF_SYNTH_INTEL_EXSTOP:
1954
		return perf_sample__fprintf_synth_exstop(sample, fp);
1955
	case PERF_SYNTH_INTEL_PWRX:
1956
		return perf_sample__fprintf_synth_pwrx(sample, fp);
1957
	case PERF_SYNTH_INTEL_CBR:
1958
		return perf_sample__fprintf_synth_cbr(sample, fp);
1959 1960
	case PERF_SYNTH_INTEL_PSB:
		return perf_sample__fprintf_synth_psb(sample, fp);
1961 1962
	case PERF_SYNTH_INTEL_EVT:
		return perf_sample__fprintf_synth_evt(sample, fp);
1963 1964
	case PERF_SYNTH_INTEL_IFLAG_CHG:
		return perf_sample__fprintf_synth_iflag_chg(sample, fp);
1965 1966 1967
	default:
		break;
	}
1968 1969

	return 0;
1970 1971
}

1972
static int evlist__max_name_len(struct evlist *evlist)
1973
{
1974
	struct evsel *evsel;
1975 1976
	int max = 0;

1977
	evlist__for_each_entry(evlist, evsel) {
1978
		int len = strlen(evsel__name(evsel));
1979 1980 1981 1982 1983 1984 1985

		max = MAX(len, max);
	}

	return max;
}

1986
static int data_src__fprintf(u64 data_src, FILE *fp)
1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999
{
	struct mem_info mi = { .data_src.val = data_src };
	char decode[100];
	char out[100];
	static int maxlen;
	int len;

	perf_script__meminfo_scnprintf(decode, 100, &mi);

	len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode);
	if (maxlen < len)
		maxlen = len;

2000
	return fprintf(fp, "%-*s", maxlen, out);
2001 2002
}

2003 2004 2005
struct metric_ctx {
	struct perf_sample	*sample;
	struct thread		*thread;
2006
	struct evsel	*evsel;
2007 2008 2009
	FILE 			*fp;
};

2010 2011
static void script_print_metric(struct perf_stat_config *config __maybe_unused,
				void *ctx, const char *color,
2012 2013 2014 2015 2016 2017 2018
			        const char *fmt,
			        const char *unit, double val)
{
	struct metric_ctx *mctx = ctx;

	if (!fmt)
		return;
2019
	perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
2020
				   PERF_RECORD_SAMPLE, mctx->fp);
2021 2022 2023 2024 2025 2026 2027 2028
	fputs("\tmetric: ", mctx->fp);
	if (color)
		color_fprintf(mctx->fp, color, fmt, val);
	else
		printf(fmt, val);
	fprintf(mctx->fp, " %s\n", unit);
}

2029 2030
static void script_new_line(struct perf_stat_config *config __maybe_unused,
			    void *ctx)
2031 2032 2033
{
	struct metric_ctx *mctx = ctx;

2034
	perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
2035
				   PERF_RECORD_SAMPLE, mctx->fp);
2036 2037 2038 2039 2040
	fputs("\tmetric: ", mctx->fp);
}

static void perf_sample__fprint_metric(struct perf_script *script,
				       struct thread *thread,
2041
				       struct evsel *evsel,
2042 2043 2044
				       struct perf_sample *sample,
				       FILE *fp)
{
2045
	struct evsel *leader = evsel__leader(evsel);
2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056
	struct perf_stat_output_ctx ctx = {
		.print_metric = script_print_metric,
		.new_line = script_new_line,
		.ctx = &(struct metric_ctx) {
				.sample = sample,
				.thread = thread,
				.evsel  = evsel,
				.fp     = fp,
			 },
		.force_header = false,
	};
2057
	struct evsel *ev2;
2058 2059 2060
	u64 val;

	if (!evsel->stats)
2061
		evlist__alloc_stats(&stat_config, script->session->evlist, /*alloc_raw=*/false);
2062
	if (evsel_script(leader)->gnum++ == 0)
2063 2064 2065
		perf_stat__reset_shadow_stats();
	val = sample->period * evsel->scale;
	evsel_script(evsel)->val = val;
2066 2067
	if (evsel_script(leader)->gnum == leader->core.nr_members) {
		for_each_group_member (ev2, leader) {
2068
			perf_stat__print_shadow_stats(&stat_config, ev2,
2069 2070 2071
						      evsel_script(ev2)->val,
						      sample->cpu,
						      &ctx,
Ian Rogers's avatar
Ian Rogers committed
2072
						      NULL);
2073
		}
2074
		evsel_script(leader)->gnum = 0;
2075 2076 2077
	}
}

2078
static bool show_event(struct perf_sample *sample,
2079
		       struct evsel *evsel,
2080
		       struct thread *thread,
2081 2082
		       struct addr_location *al,
		       struct addr_location *addr_al)
2083
{
2084
	int depth = thread_stack__depth(thread, sample->cpu);
2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097

	if (!symbol_conf.graph_function)
		return true;

	if (thread->filter) {
		if (depth <= thread->filter_entry_depth) {
			thread->filter = false;
			return false;
		}
		return true;
	} else {
		const char *s = symbol_conf.graph_function;
		u64 ip;
2098
		const char *name = resolve_branch_sym(sample, evsel, thread, al, addr_al,
2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119
				&ip);
		unsigned nlen;

		if (!name)
			return false;
		nlen = strlen(name);
		while (*s) {
			unsigned len = strcspn(s, ",");
			if (nlen == len && !strncmp(name, s, len)) {
				thread->filter = true;
				thread->filter_entry_depth = depth;
				return true;
			}
			s += len;
			if (*s == ',')
				s++;
		}
		return false;
	}
}

2120
static void process_event(struct perf_script *script,
2121
			  struct perf_sample *sample, struct evsel *evsel,
2122
			  struct addr_location *al,
2123
			  struct addr_location *addr_al,
2124
			  struct machine *machine)
2125
{
2126
	struct thread *thread = al->thread;
2127
	struct perf_event_attr *attr = &evsel->core.attr;
2128
	unsigned int type = output_type(attr->type);
2129
	struct evsel_script *es = evsel->priv;
2130
	FILE *fp = es->fp;
2131
	char str[PAGE_SIZE_NAME_LEN];
2132
	const char *arch = perf_env__arch(machine->env);
2133

2134
	if (output[type].fields == 0)
2135 2136
		return;

2137 2138
	++es->samples;

2139
	perf_sample__fprintf_start(script, sample, thread, evsel,
2140
				   PERF_RECORD_SAMPLE, fp);
2141

2142
	if (PRINT_FIELD(PERIOD))
2143
		fprintf(fp, "%10" PRIu64 " ", sample->period);
2144

2145
	if (PRINT_FIELD(EVNAME)) {
2146
		const char *evname = evsel__name(evsel);
2147 2148

		if (!script->name_width)
2149
			script->name_width = evlist__max_name_len(script->session->evlist);
2150

2151
		fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]");
2152 2153
	}

2154
	if (print_flags)
2155
		perf_sample__fprintf_flags(sample->flags, fp);
2156

2157
	if (is_bts_event(attr)) {
2158
		perf_sample__fprintf_bts(sample, evsel, thread, al, addr_al, machine, fp);
2159 2160
		return;
	}
2161
#ifdef HAVE_LIBTRACEEVENT
2162
	if (PRINT_FIELD(TRACE) && sample->raw_data) {
2163 2164 2165
		event_format__fprintf(evsel->tp_format, sample->cpu,
				      sample->raw_data, sample->raw_size, fp);
	}
2166
#endif
2167
	if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
2168
		perf_sample__fprintf_synth(sample, evsel, fp);
2169

2170
	if (PRINT_FIELD(ADDR))
2171
		perf_sample__fprintf_addr(sample, thread, attr, fp);
2172

2173
	if (PRINT_FIELD(DATA_SRC))
2174
		data_src__fprintf(sample->data_src, fp);
2175 2176

	if (PRINT_FIELD(WEIGHT))
2177
		fprintf(fp, "%16" PRIu64, sample->weight);
2178

2179 2180 2181
	if (PRINT_FIELD(INS_LAT))
		fprintf(fp, "%16" PRIu16, sample->ins_lat);

2182 2183 2184
	if (PRINT_FIELD(RETIRE_LAT))
		fprintf(fp, "%16" PRIu16, sample->retire_lat);

2185
	if (PRINT_FIELD(IP)) {
2186
		struct callchain_cursor *cursor = NULL;
2187

2188 2189 2190
		if (script->stitch_lbr)
			al->thread->lbr_stitch_enable = true;

2191
		if (symbol_conf.use_callchain && sample->callchain &&
2192
		    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
2193
					      sample, NULL, NULL, scripting_max_stack) == 0)
2194
			cursor = &callchain_cursor;
2195

2196
		fputc(cursor ? '\n' : ' ', fp);
2197 2198
		sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor,
				    symbol_conf.bt_stop_list, fp);
2199 2200
	}

2201
	if (PRINT_FIELD(IREGS))
2202
		perf_sample__fprintf_iregs(sample, attr, arch, fp);
2203

2204
	if (PRINT_FIELD(UREGS))
2205
		perf_sample__fprintf_uregs(sample, attr, arch, fp);
2206

2207
	if (PRINT_FIELD(BRSTACK))
2208
		perf_sample__fprintf_brstack(sample, thread, attr, fp);
2209
	else if (PRINT_FIELD(BRSTACKSYM))
2210
		perf_sample__fprintf_brstacksym(sample, thread, attr, fp);
2211
	else if (PRINT_FIELD(BRSTACKOFF))
2212
		perf_sample__fprintf_brstackoff(sample, thread, attr, fp);
2213

2214
	if (evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
2215 2216
		perf_sample__fprintf_bpf_output(sample, fp);
	perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
2217 2218

	if (PRINT_FIELD(PHYS_ADDR))
2219
		fprintf(fp, "%16" PRIx64, sample->phys_addr);
2220

2221 2222 2223
	if (PRINT_FIELD(DATA_PAGE_SIZE))
		fprintf(fp, " %s", get_page_size_name(sample->data_page_size, str));

2224 2225 2226
	if (PRINT_FIELD(CODE_PAGE_SIZE))
		fprintf(fp, " %s", get_page_size_name(sample->code_page_size, str));

2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237
	if (PRINT_FIELD(CGROUP)) {
		const char *cgrp_name;
		struct cgroup *cgrp = cgroup__find(machine->env,
						   sample->cgroup);
		if (cgrp != NULL)
			cgrp_name = cgrp->name;
		else
			cgrp_name = "unknown";
		fprintf(fp, " %s", cgrp_name);
	}

2238 2239
	perf_sample__fprintf_ipc(sample, attr, fp);

2240
	fprintf(fp, "\n");
2241

2242 2243 2244 2245 2246 2247
	if (PRINT_FIELD(SRCCODE)) {
		if (map__fprintf_srccode(al->map, al->addr, stdout,
					 &thread->srccode_state))
			printf("\n");
	}

2248 2249
	if (PRINT_FIELD(METRIC))
		perf_sample__fprint_metric(script, thread, evsel, sample, fp);
2250

2251
	if (verbose > 0)
2252
		fflush(fp);
2253 2254
}

Tom Zanussi's avatar
Tom Zanussi committed
2255 2256
static struct scripting_ops	*scripting_ops;

2257
static void __process_stat(struct evsel *counter, u64 tstamp)
2258
{
2259
	int nthreads = perf_thread_map__nr(counter->core.threads);
2260 2261
	int idx, thread;
	struct perf_cpu cpu;
2262 2263 2264 2265 2266 2267 2268 2269 2270
	static int header_printed;

	if (!header_printed) {
		printf("%3s %8s %15s %15s %15s %15s %s\n",
		       "CPU", "THREAD", "VAL", "ENA", "RUN", "TIME", "EVENT");
		header_printed = 1;
	}

	for (thread = 0; thread < nthreads; thread++) {
2271
		perf_cpu_map__for_each_cpu(cpu, idx, evsel__cpus(counter)) {
2272 2273
			struct perf_counts_values *counts;

2274
			counts = perf_counts(counter->counts, idx, thread);
2275 2276

			printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n",
2277
				cpu.cpu,
2278
				perf_thread_map__pid(counter->core.threads, thread),
2279 2280 2281 2282
				counts->val,
				counts->ena,
				counts->run,
				tstamp,
2283
				evsel__name(counter));
2284 2285 2286 2287
		}
	}
}

2288
static void process_stat(struct evsel *counter, u64 tstamp)
2289 2290 2291
{
	if (scripting_ops && scripting_ops->process_stat)
		scripting_ops->process_stat(&stat_config, counter, tstamp);
2292 2293
	else
		__process_stat(counter, tstamp);
2294 2295 2296 2297 2298 2299 2300 2301
}

static void process_stat_interval(u64 tstamp)
{
	if (scripting_ops && scripting_ops->process_stat_interval)
		scripting_ops->process_stat_interval(tstamp);
}

Tom Zanussi's avatar
Tom Zanussi committed
2302 2303
static void setup_scripting(void)
{
2304
#ifdef HAVE_LIBTRACEEVENT
2305
	setup_perl_scripting();
2306
#endif
2307
	setup_python_scripting();
Tom Zanussi's avatar
Tom Zanussi committed
2308 2309
}

2310 2311
static int flush_scripting(void)
{
2312
	return scripting_ops ? scripting_ops->flush_script() : 0;
2313 2314
}

Tom Zanussi's avatar
Tom Zanussi committed
2315 2316
static int cleanup_scripting(void)
{
2317
	pr_debug("\nperf script stopped\n");
2318

2319
	return scripting_ops ? scripting_ops->stop_script() : 0;
Tom Zanussi's avatar
Tom Zanussi committed
2320 2321
}

2322 2323
static bool filter_cpu(struct perf_sample *sample)
{
2324
	if (cpu_list && sample->cpu != (u32)-1)
2325 2326 2327 2328
		return !test_bit(sample->cpu, cpu_bitmap);
	return false;
}

2329
static int process_sample_event(struct perf_tool *tool,
2330
				union perf_event *event,
2331
				struct perf_sample *sample,
2332
				struct evsel *evsel,
2333
				struct machine *machine)
2334
{
2335
	struct perf_script *scr = container_of(tool, struct perf_script, tool);
2336
	struct addr_location al;
2337
	struct addr_location addr_al;
2338
	int ret = 0;
2339

2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350
	/* Set thread to NULL to indicate addr_al and al are not initialized */
	addr_al.thread = NULL;
	al.thread = NULL;

	ret = dlfilter__filter_event_early(dlfilter, event, sample, evsel, machine, &al, &addr_al);
	if (ret) {
		if (ret > 0)
			ret = 0;
		goto out_put;
	}

2351 2352
	if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num,
					  sample->time)) {
2353
		goto out_put;
2354
	}
2355

2356 2357 2358 2359 2360 2361
	if (debug_mode) {
		if (sample->time < last_timestamp) {
			pr_err("Samples misordered, previous: %" PRIu64
				" this: %" PRIu64 "\n", last_timestamp,
				sample->time);
			nr_unordered++;
2362
		}
2363
		last_timestamp = sample->time;
2364
		goto out_put;
2365
	}
2366

2367
	if (filter_cpu(sample))
2368
		goto out_put;
2369

2370
	if (!al.thread && machine__resolve(machine, &al, sample) < 0) {
2371 2372
		pr_err("problem processing %d event, skipping it.\n",
		       event->header.type);
2373 2374
		ret = -1;
		goto out_put;
2375 2376 2377
	}

	if (al.filtered)
2378
		goto out_put;
2379

2380
	if (!show_event(sample, evsel, al.thread, &al, &addr_al))
2381 2382 2383 2384 2385
		goto out_put;

	if (evswitch__discard(&scr->evswitch, evsel))
		goto out_put;

2386 2387 2388 2389 2390 2391 2392
	ret = dlfilter__filter_event(dlfilter, event, sample, evsel, machine, &al, &addr_al);
	if (ret) {
		if (ret > 0)
			ret = 0;
		goto out_put;
	}

2393 2394 2395 2396 2397
	if (scripting_ops) {
		struct addr_location *addr_al_ptr = NULL;

		if ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
		    sample_addr_correlates_sym(&evsel->core.attr)) {
2398 2399
			if (!addr_al.thread)
				thread__resolve(al.thread, &addr_al, sample);
2400 2401 2402 2403
			addr_al_ptr = &addr_al;
		}
		scripting_ops->process_event(event, sample, evsel, &al, addr_al_ptr);
	} else {
2404
		process_event(scr, sample, evsel, &al, &addr_al, machine);
2405
	}
2406

2407
out_put:
2408 2409
	if (al.thread)
		addr_location__put(&al);
2410
	return ret;
2411 2412
}

2413
static int process_attr(struct perf_tool *tool, union perf_event *event,
2414
			struct evlist **pevlist)
2415 2416
{
	struct perf_script *scr = container_of(tool, struct perf_script, tool);
2417
	struct evlist *evlist;
2418
	struct evsel *evsel, *pos;
2419
	u64 sample_type;
2420
	int err;
2421
	static struct evsel_script *es;
2422 2423 2424 2425 2426 2427

	err = perf_event__process_attr(tool, event, pevlist);
	if (err)
		return err;

	evlist = *pevlist;
2428
	evsel = evlist__last(*pevlist);
2429

2430 2431
	if (!evsel->priv) {
		if (scr->per_event_dump) {
2432
			evsel->priv = evsel_script__new(evsel, scr->session->data);
2433 2434 2435 2436 2437 2438 2439 2440 2441
		} else {
			es = zalloc(sizeof(*es));
			if (!es)
				return -ENOMEM;
			es->fp = stdout;
			evsel->priv = es;
		}
	}

2442 2443
	if (evsel->core.attr.type >= PERF_TYPE_MAX &&
	    evsel->core.attr.type != PERF_TYPE_SYNTH)
2444 2445
		return 0;

2446
	evlist__for_each_entry(evlist, pos) {
2447
		if (pos->core.attr.type == evsel->core.attr.type && pos != evsel)
2448 2449 2450
			return 0;
	}

2451
	if (evsel->core.attr.sample_type) {
2452
		err = evsel__check_attr(evsel, scr->session);
2453 2454 2455
		if (err)
			return err;
	}
2456

2457 2458 2459 2460
	/*
	 * Check if we need to enable callchains based
	 * on events sample_type.
	 */
2461
	sample_type = evlist__combined_sample_type(evlist);
2462
	callchain_param_setup(sample_type, perf_env__arch((*pevlist)->env));
2463

2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475
	/* Enable fields for callchain entries */
	if (symbol_conf.use_callchain &&
	    (sample_type & PERF_SAMPLE_CALLCHAIN ||
	     sample_type & PERF_SAMPLE_BRANCH_STACK ||
	     (sample_type & PERF_SAMPLE_REGS_USER &&
	      sample_type & PERF_SAMPLE_STACK_USER))) {
		int type = output_type(evsel->core.attr.type);

		if (!(output[type].user_unset_fields & PERF_OUTPUT_IP))
			output[type].fields |= PERF_OUTPUT_IP;
		if (!(output[type].user_unset_fields & PERF_OUTPUT_SYM))
			output[type].fields |= PERF_OUTPUT_SYM;
2476 2477
	}
	set_print_ip_opts(&evsel->core.attr);
2478
	return 0;
2479 2480
}

2481 2482 2483 2484 2485
static int 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)
2486 2487 2488
{
	struct perf_script *script = container_of(tool, struct perf_script, tool);
	struct perf_session *session = script->session;
2489
	struct evsel *evsel = evlist__id2evsel(session->evlist, sample->id);
2490
	struct thread *thread = NULL;
2491

2492 2493 2494 2495 2496
	if (evsel && !evsel->core.attr.sample_id_all) {
		sample->cpu = 0;
		sample->time = timestamp;
		sample->pid = pid;
		sample->tid = tid;
2497 2498
	}

2499 2500
	if (filter_cpu(sample))
		return 0;
2501

2502 2503 2504
	if (tid != -1)
		thread = machine__findnew_thread(machine, pid, tid);

2505
	if (evsel) {
2506
		perf_sample__fprintf_start(script, sample, thread, evsel,
2507
					   event->header.type, stdout);
2508
	}
2509

2510
	perf_event__fprintf(event, machine, stdout);
2511

2512
	thread__put(thread);
2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533

	return 0;
}

static int print_event(struct perf_tool *tool, union perf_event *event,
		       struct perf_sample *sample, struct machine *machine,
		       pid_t pid, pid_t tid)
{
	return print_event_with_time(tool, event, sample, machine, pid, tid, 0);
}

static int process_comm_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
	if (perf_event__process_comm(tool, event, sample, machine) < 0)
		return -1;

	return print_event(tool, event, sample, machine, event->comm.pid,
			   event->comm.tid);
2534 2535
}

2536 2537 2538 2539 2540 2541
static int process_namespaces_event(struct perf_tool *tool,
				    union perf_event *event,
				    struct perf_sample *sample,
				    struct machine *machine)
{
	if (perf_event__process_namespaces(tool, event, sample, machine) < 0)
2542
		return -1;
2543

2544 2545
	return print_event(tool, event, sample, machine, event->namespaces.pid,
			   event->namespaces.tid);
2546 2547
}

2548 2549 2550 2551 2552 2553
static int process_cgroup_event(struct perf_tool *tool,
				union perf_event *event,
				struct perf_sample *sample,
				struct machine *machine)
{
	if (perf_event__process_cgroup(tool, event, sample, machine) < 0)
2554
		return -1;
2555

2556 2557
	return print_event(tool, event, sample, machine, sample->pid,
			    sample->tid);
2558 2559
}

2560 2561 2562 2563 2564 2565 2566 2567
static int process_fork_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
	if (perf_event__process_fork(tool, event, sample, machine) < 0)
		return -1;

2568 2569 2570
	return print_event_with_time(tool, event, sample, machine,
				     event->fork.pid, event->fork.tid,
				     event->fork.time);
2571 2572 2573 2574 2575 2576
}
static int process_exit_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
2577 2578 2579
	/* Print before 'exit' deletes anything */
	if (print_event_with_time(tool, event, sample, machine, event->fork.pid,
				  event->fork.tid, event->fork.time))
2580 2581
		return -1;

2582
	return perf_event__process_exit(tool, event, sample, machine);
2583 2584
}

2585 2586 2587 2588 2589 2590 2591 2592
static int process_mmap_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
	if (perf_event__process_mmap(tool, event, sample, machine) < 0)
		return -1;

2593 2594
	return print_event(tool, event, sample, machine, event->mmap.pid,
			   event->mmap.tid);
2595 2596 2597 2598 2599 2600 2601 2602 2603 2604
}

static int process_mmap2_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
	if (perf_event__process_mmap2(tool, event, sample, machine) < 0)
		return -1;

2605 2606
	return print_event(tool, event, sample, machine, event->mmap2.pid,
			   event->mmap2.tid);
2607 2608
}

2609 2610 2611 2612 2613 2614 2615 2616 2617 2618
static int process_switch_event(struct perf_tool *tool,
				union perf_event *event,
				struct perf_sample *sample,
				struct machine *machine)
{
	struct perf_script *script = container_of(tool, struct perf_script, tool);

	if (perf_event__process_switch(tool, event, sample, machine) < 0)
		return -1;

2619
	if (scripting_ops && scripting_ops->process_switch && !filter_cpu(sample))
2620 2621 2622 2623 2624
		scripting_ops->process_switch(event, sample, machine);

	if (!script->show_switch_events)
		return 0;

2625 2626
	return print_event(tool, event, sample, machine, sample->pid,
			   sample->tid);
2627 2628
}

2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639
static int process_auxtrace_error(struct perf_session *session,
				  union perf_event *event)
{
	if (scripting_ops && scripting_ops->process_auxtrace_error) {
		scripting_ops->process_auxtrace_error(session, event);
		return 0;
	}

	return perf_event__process_auxtrace_error(session, event);
}

2640 2641 2642 2643 2644 2645
static int
process_lost_event(struct perf_tool *tool,
		   union perf_event *event,
		   struct perf_sample *sample,
		   struct machine *machine)
{
2646 2647
	return print_event(tool, event, sample, machine, sample->pid,
			   sample->tid);
2648 2649
}

2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660
static int
process_throttle_event(struct perf_tool *tool __maybe_unused,
		       union perf_event *event,
		       struct perf_sample *sample,
		       struct machine *machine)
{
	if (scripting_ops && scripting_ops->process_throttle)
		scripting_ops->process_throttle(event, sample, machine);
	return 0;
}

2661 2662 2663 2664 2665 2666
static int
process_finished_round_event(struct perf_tool *tool __maybe_unused,
			     union perf_event *event,
			     struct ordered_events *oe __maybe_unused)

{
2667
	perf_event__fprintf(event, NULL, stdout);
2668 2669 2670
	return 0;
}

2671 2672 2673 2674 2675 2676 2677 2678 2679
static int
process_bpf_events(struct perf_tool *tool __maybe_unused,
		   union perf_event *event,
		   struct perf_sample *sample,
		   struct machine *machine)
{
	if (machine__process_ksymbol(machine, event, sample) < 0)
		return -1;

2680 2681
	return print_event(tool, event, sample, machine, sample->pid,
			   sample->tid);
2682 2683
}

2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695
static int process_text_poke_events(struct perf_tool *tool,
				    union perf_event *event,
				    struct perf_sample *sample,
				    struct machine *machine)
{
	if (perf_event__process_text_poke(tool, event, sample, machine) < 0)
		return -1;

	return print_event(tool, event, sample, machine, sample->pid,
			   sample->tid);
}

2696
static void sig_handler(int sig __maybe_unused)
2697 2698 2699 2700
{
	session_done = 1;
}

2701 2702
static void perf_script__fclose_per_event_dump(struct perf_script *script)
{
2703
	struct evlist *evlist = script->session->evlist;
2704
	struct evsel *evsel;
2705 2706 2707 2708

	evlist__for_each_entry(evlist, evsel) {
		if (!evsel->priv)
			break;
2709
		evsel_script__delete(evsel->priv);
2710 2711 2712 2713 2714 2715
		evsel->priv = NULL;
	}
}

static int perf_script__fopen_per_event_dump(struct perf_script *script)
{
2716
	struct evsel *evsel;
2717 2718

	evlist__for_each_entry(script->session->evlist, evsel) {
2719 2720 2721
		/*
		 * Already setup? I.e. we may be called twice in cases like
		 * Intel PT, one for the intel_pt// and dummy events, then
2722
		 * for the evsels synthesized from the auxtrace info.
2723 2724 2725 2726 2727 2728
		 *
		 * Ses perf_script__process_auxtrace_info.
		 */
		if (evsel->priv != NULL)
			continue;

2729
		evsel->priv = evsel_script__new(evsel, script->session->data);
2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742
		if (evsel->priv == NULL)
			goto out_err_fclose;
	}

	return 0;

out_err_fclose:
	perf_script__fclose_per_event_dump(script);
	return -1;
}

static int perf_script__setup_per_event_dump(struct perf_script *script)
{
2743 2744
	struct evsel *evsel;
	static struct evsel_script es_stdout;
2745 2746 2747 2748

	if (script->per_event_dump)
		return perf_script__fopen_per_event_dump(script);

2749 2750
	es_stdout.fp = stdout;

2751
	evlist__for_each_entry(script->session->evlist, evsel)
2752
		evsel->priv = &es_stdout;
2753 2754 2755 2756

	return 0;
}

2757 2758
static void perf_script__exit_per_event_dump_stats(struct perf_script *script)
{
2759
	struct evsel *evsel;
2760 2761

	evlist__for_each_entry(script->session->evlist, evsel) {
2762
		struct evsel_script *es = evsel->priv;
2763

2764 2765
		evsel_script__fprintf(es, stdout);
		evsel_script__delete(es);
2766 2767 2768 2769
		evsel->priv = NULL;
	}
}

2770 2771 2772 2773 2774 2775
static void perf_script__exit(struct perf_script *script)
{
	perf_thread_map__put(script->threads);
	perf_cpu_map__put(script->cpus);
}

2776
static int __cmd_script(struct perf_script *script)
2777
{
2778 2779
	int ret;

2780 2781
	signal(SIGINT, sig_handler);

2782 2783 2784 2785 2786 2787
	/* override event processing functions */
	if (script->show_task_events) {
		script->tool.comm = process_comm_event;
		script->tool.fork = process_fork_event;
		script->tool.exit = process_exit_event;
	}
2788 2789 2790 2791
	if (script->show_mmap_events) {
		script->tool.mmap = process_mmap_event;
		script->tool.mmap2 = process_mmap2_event;
	}
2792
	if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch))
2793
		script->tool.context_switch = process_switch_event;
2794 2795
	if (scripting_ops && scripting_ops->process_auxtrace_error)
		script->tool.auxtrace_error = process_auxtrace_error;
2796 2797
	if (script->show_namespace_events)
		script->tool.namespaces = process_namespaces_event;
2798 2799
	if (script->show_cgroup_events)
		script->tool.cgroup = process_cgroup_event;
2800 2801
	if (script->show_lost_events)
		script->tool.lost = process_lost_event;
2802 2803 2804 2805
	if (script->show_round_events) {
		script->tool.ordered_events = false;
		script->tool.finished_round = process_finished_round_event;
	}
2806
	if (script->show_bpf_events) {
2807 2808
		script->tool.ksymbol = process_bpf_events;
		script->tool.bpf     = process_bpf_events;
2809
	}
2810 2811 2812 2813
	if (script->show_text_poke_events) {
		script->tool.ksymbol   = process_bpf_events;
		script->tool.text_poke = process_text_poke_events;
	}
2814

2815 2816 2817 2818 2819
	if (perf_script__setup_per_event_dump(script)) {
		pr_err("Couldn't create the per event dump files\n");
		return -1;
	}

2820
	ret = perf_session__process_events(script->session);
2821

2822
	if (script->per_event_dump)
2823
		perf_script__exit_per_event_dump_stats(script);
2824

2825
	if (debug_mode)
2826
		pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
2827 2828

	return ret;
2829 2830
}

Tom Zanussi's avatar
Tom Zanussi committed
2831 2832 2833
struct script_spec {
	struct list_head	node;
	struct scripting_ops	*ops;
2834
	char			spec[];
Tom Zanussi's avatar
Tom Zanussi committed
2835 2836
};

2837
static LIST_HEAD(script_specs);
Tom Zanussi's avatar
Tom Zanussi committed
2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874

static struct script_spec *script_spec__new(const char *spec,
					    struct scripting_ops *ops)
{
	struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);

	if (s != NULL) {
		strcpy(s->spec, spec);
		s->ops = ops;
	}

	return s;
}

static void script_spec__add(struct script_spec *s)
{
	list_add_tail(&s->node, &script_specs);
}

static struct script_spec *script_spec__find(const char *spec)
{
	struct script_spec *s;

	list_for_each_entry(s, &script_specs, node)
		if (strcasecmp(s->spec, spec) == 0)
			return s;
	return NULL;
}

int script_spec_register(const char *spec, struct scripting_ops *ops)
{
	struct script_spec *s;

	s = script_spec__find(spec);
	if (s)
		return -1;

2875
	s = script_spec__new(spec, ops);
Tom Zanussi's avatar
Tom Zanussi committed
2876 2877
	if (!s)
		return -1;
2878 2879
	else
		script_spec__add(s);
Tom Zanussi's avatar
Tom Zanussi committed
2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898

	return 0;
}

static struct scripting_ops *script_spec__lookup(const char *spec)
{
	struct script_spec *s = script_spec__find(spec);
	if (!s)
		return NULL;

	return s->ops;
}

static void list_available_languages(void)
{
	struct script_spec *s;

	fprintf(stderr, "\n");
	fprintf(stderr, "Scripting language extensions (used in "
2899
		"perf script -s [spec:]script.[spec]):\n\n");
Tom Zanussi's avatar
Tom Zanussi committed
2900 2901 2902 2903 2904 2905 2906

	list_for_each_entry(s, &script_specs, node)
		fprintf(stderr, "  %-42s [%s]\n", s->spec, s->ops->name);

	fprintf(stderr, "\n");
}

2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937
/* Find script file relative to current directory or exec path */
static char *find_script(const char *script)
{
	char path[PATH_MAX];

	if (!scripting_ops) {
		const char *ext = strrchr(script, '.');

		if (!ext)
			return NULL;

		scripting_ops = script_spec__lookup(++ext);
		if (!scripting_ops)
			return NULL;
	}

	if (access(script, R_OK)) {
		char *exec_path = get_argv_exec_path();

		if (!exec_path)
			return NULL;
		snprintf(path, sizeof(path), "%s/scripts/%s/%s",
			 exec_path, scripting_ops->dirname, script);
		free(exec_path);
		script = path;
		if (access(script, R_OK))
			return NULL;
	}
	return strdup(script);
}

2938 2939
static int parse_scriptname(const struct option *opt __maybe_unused,
			    const char *str, int unset __maybe_unused)
Tom Zanussi's avatar
Tom Zanussi committed
2940 2941 2942 2943 2944
{
	char spec[PATH_MAX];
	const char *script, *ext;
	int len;

2945
	if (strcmp(str, "lang") == 0) {
Tom Zanussi's avatar
Tom Zanussi committed
2946
		list_available_languages();
2947
		exit(0);
Tom Zanussi's avatar
Tom Zanussi committed
2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966
	}

	script = strchr(str, ':');
	if (script) {
		len = script - str;
		if (len >= PATH_MAX) {
			fprintf(stderr, "invalid language specifier");
			return -1;
		}
		strncpy(spec, str, len);
		spec[len] = '\0';
		scripting_ops = script_spec__lookup(spec);
		if (!scripting_ops) {
			fprintf(stderr, "invalid language specifier");
			return -1;
		}
		script++;
	} else {
		script = str;
2967
		ext = strrchr(script, '.');
Tom Zanussi's avatar
Tom Zanussi committed
2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978
		if (!ext) {
			fprintf(stderr, "invalid script extension");
			return -1;
		}
		scripting_ops = script_spec__lookup(++ext);
		if (!scripting_ops) {
			fprintf(stderr, "invalid script extension");
			return -1;
		}
	}

2979 2980 2981
	script_name = find_script(script);
	if (!script_name)
		script_name = strdup(script);
Tom Zanussi's avatar
Tom Zanussi committed
2982 2983 2984 2985

	return 0;
}

2986 2987
static int parse_output_fields(const struct option *opt __maybe_unused,
			    const char *arg, int unset __maybe_unused)
2988
{
2989
	char *tok, *strtok_saveptr = NULL;
2990
	int i, imax = ARRAY_SIZE(all_output_options);
2991
	int j;
2992 2993
	int rc = 0;
	char *str = strdup(arg);
2994
	int type = -1;
2995
	enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;
2996 2997 2998 2999

	if (!str)
		return -ENOMEM;

3000 3001 3002
	/* first word can state for which event type the user is specifying
	 * the fields. If no type exists, the specified fields apply to all
	 * event types found in the file minus the invalid fields for a type.
3003
	 */
3004 3005 3006 3007 3008 3009 3010 3011 3012 3013
	tok = strchr(str, ':');
	if (tok) {
		*tok = '\0';
		tok++;
		if (!strcmp(str, "hw"))
			type = PERF_TYPE_HARDWARE;
		else if (!strcmp(str, "sw"))
			type = PERF_TYPE_SOFTWARE;
		else if (!strcmp(str, "trace"))
			type = PERF_TYPE_TRACEPOINT;
3014 3015
		else if (!strcmp(str, "raw"))
			type = PERF_TYPE_RAW;
3016 3017
		else if (!strcmp(str, "break"))
			type = PERF_TYPE_BREAKPOINT;
3018 3019
		else if (!strcmp(str, "synth"))
			type = OUTPUT_TYPE_SYNTH;
3020 3021
		else {
			fprintf(stderr, "Invalid event type in field string.\n");
3022 3023
			rc = -EINVAL;
			goto out;
3024 3025 3026 3027 3028 3029
		}

		if (output[type].user_set)
			pr_warning("Overriding previous field request for %s events.\n",
				   event_type(type));

3030 3031 3032 3033
		/* Don't override defaults for +- */
		if (strchr(tok, '+') || strchr(tok, '-'))
			goto parse;

3034 3035
		output[type].fields = 0;
		output[type].user_set = true;
3036
		output[type].wildcard_set = false;
3037 3038 3039 3040 3041 3042 3043 3044 3045 3046

	} else {
		tok = str;
		if (strlen(str) == 0) {
			fprintf(stderr,
				"Cannot set fields to 'none' for all event types.\n");
			rc = -EINVAL;
			goto out;
		}

3047 3048 3049 3050
		/* Don't override defaults for +- */
		if (strchr(str, '+') || strchr(str, '-'))
			goto parse;

3051 3052 3053
		if (output_set_by_user())
			pr_warning("Overriding previous field request for all events.\n");

3054
		for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
3055 3056
			output[j].fields = 0;
			output[j].user_set = true;
3057
			output[j].wildcard_set = true;
3058
		}
3059 3060
	}

3061
parse:
3062
	for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078
		if (*tok == '+') {
			if (change == SET)
				goto out_badmix;
			change = ADD;
			tok++;
		} else if (*tok == '-') {
			if (change == SET)
				goto out_badmix;
			change = REMOVE;
			tok++;
		} else {
			if (change != SET && change != DEFAULT)
				goto out_badmix;
			change = SET;
		}

3079
		for (i = 0; i < imax; ++i) {
3080
			if (strcmp(tok, all_output_options[i].str) == 0)
3081 3082
				break;
		}
3083
		if (i == imax && strcmp(tok, "flags") == 0) {
3084
			print_flags = change != REMOVE;
3085 3086
			continue;
		}
3087
		if (i == imax) {
3088
			fprintf(stderr, "Invalid field requested.\n");
3089
			rc = -EINVAL;
3090
			goto out;
3091 3092
		}

3093 3094 3095 3096
		if (type == -1) {
			/* add user option to all events types for
			 * which it is valid
			 */
3097
			for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
3098 3099 3100
				if (output[j].invalid_fields & all_output_options[i].field) {
					pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
						   all_output_options[i].str, event_type(j));
3101
				} else {
3102
					if (change == REMOVE) {
3103
						output[j].fields &= ~all_output_options[i].field;
3104
						output[j].user_set_fields &= ~all_output_options[i].field;
3105
						output[j].user_unset_fields |= all_output_options[i].field;
3106
					} else {
3107
						output[j].fields |= all_output_options[i].field;
3108
						output[j].user_set_fields |= all_output_options[i].field;
3109
						output[j].user_unset_fields &= ~all_output_options[i].field;
3110
					}
3111 3112
					output[j].user_set = true;
					output[j].wildcard_set = true;
3113
				}
3114 3115 3116 3117 3118 3119 3120 3121 3122
			}
		} else {
			if (output[type].invalid_fields & all_output_options[i].field) {
				fprintf(stderr, "\'%s\' not valid for %s events.\n",
					 all_output_options[i].str, event_type(type));

				rc = -EINVAL;
				goto out;
			}
3123 3124 3125 3126
			if (change == REMOVE)
				output[type].fields &= ~all_output_options[i].field;
			else
				output[type].fields |= all_output_options[i].field;
3127 3128
			output[type].user_set = true;
			output[type].wildcard_set = true;
3129
		}
3130 3131
	}

3132 3133 3134 3135 3136 3137
	if (type >= 0) {
		if (output[type].fields == 0) {
			pr_debug("No fields requested for %s type. "
				 "Events will not be displayed.\n", event_type(type));
		}
	}
3138
	goto out;
3139

3140 3141 3142
out_badmix:
	fprintf(stderr, "Cannot mix +-field with overridden fields\n");
	rc = -EINVAL;
3143
out:
3144 3145 3146 3147
	free(str);
	return rc;
}

3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160
#define for_each_lang(scripts_path, scripts_dir, lang_dirent)		\
	while ((lang_dirent = readdir(scripts_dir)) != NULL)		\
		if ((lang_dirent->d_type == DT_DIR ||			\
		     (lang_dirent->d_type == DT_UNKNOWN &&		\
		      is_directory(scripts_path, lang_dirent))) &&	\
		    (strcmp(lang_dirent->d_name, ".")) &&		\
		    (strcmp(lang_dirent->d_name, "..")))

#define for_each_script(lang_path, lang_dir, script_dirent)		\
	while ((script_dirent = readdir(lang_dir)) != NULL)		\
		if (script_dirent->d_type != DT_DIR &&			\
		    (script_dirent->d_type != DT_UNKNOWN ||		\
		     !is_directory(lang_path, script_dirent)))
3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172


#define RECORD_SUFFIX			"-record"
#define REPORT_SUFFIX			"-report"

struct script_desc {
	struct list_head	node;
	char			*name;
	char			*half_liner;
	char			*args;
};

3173
static LIST_HEAD(script_descs);
3174 3175 3176 3177 3178

static struct script_desc *script_desc__new(const char *name)
{
	struct script_desc *s = zalloc(sizeof(*s));

3179
	if (s != NULL && name)
3180 3181 3182 3183 3184 3185 3186
		s->name = strdup(name);

	return s;
}

static void script_desc__delete(struct script_desc *s)
{
3187 3188 3189
	zfree(&s->name);
	zfree(&s->half_liner);
	zfree(&s->args);
3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216
	free(s);
}

static void script_desc__add(struct script_desc *s)
{
	list_add_tail(&s->node, &script_descs);
}

static struct script_desc *script_desc__find(const char *name)
{
	struct script_desc *s;

	list_for_each_entry(s, &script_descs, node)
		if (strcasecmp(s->name, name) == 0)
			return s;
	return NULL;
}

static struct script_desc *script_desc__findnew(const char *name)
{
	struct script_desc *s = script_desc__find(name);

	if (s)
		return s;

	s = script_desc__new(name);
	if (!s)
3217
		return NULL;
3218 3219 3220 3221 3222 3223

	script_desc__add(s);

	return s;
}

3224
static const char *ends_with(const char *str, const char *suffix)
3225 3226
{
	size_t suffix_len = strlen(suffix);
3227
	const char *p = str;
3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247

	if (strlen(str) > suffix_len) {
		p = str + strlen(str) - suffix_len;
		if (!strncmp(p, suffix, suffix_len))
			return p;
	}

	return NULL;
}

static int read_script_info(struct script_desc *desc, const char *filename)
{
	char line[BUFSIZ], *p;
	FILE *fp;

	fp = fopen(filename, "r");
	if (!fp)
		return -1;

	while (fgets(line, sizeof(line), fp)) {
3248
		p = skip_spaces(line);
3249 3250 3251 3252 3253 3254 3255 3256
		if (strlen(p) == 0)
			continue;
		if (*p != '#')
			continue;
		p++;
		if (strlen(p) && *p == '!')
			continue;

3257
		p = skip_spaces(p);
3258 3259 3260 3261 3262
		if (strlen(p) && p[strlen(p) - 1] == '\n')
			p[strlen(p) - 1] = '\0';

		if (!strncmp(p, "description:", strlen("description:"))) {
			p += strlen("description:");
3263
			desc->half_liner = strdup(skip_spaces(p));
3264 3265 3266 3267 3268
			continue;
		}

		if (!strncmp(p, "args:", strlen("args:"))) {
			p += strlen("args:");
3269
			desc->args = strdup(skip_spaces(p));
3270 3271 3272 3273 3274 3275 3276 3277 3278
			continue;
		}
	}

	fclose(fp);

	return 0;
}

3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296
static char *get_script_root(struct dirent *script_dirent, const char *suffix)
{
	char *script_root, *str;

	script_root = strdup(script_dirent->d_name);
	if (!script_root)
		return NULL;

	str = (char *)ends_with(script_root, suffix);
	if (!str) {
		free(script_root);
		return NULL;
	}

	*str = '\0';
	return script_root;
}

3297 3298 3299
static int list_available_scripts(const struct option *opt __maybe_unused,
				  const char *s __maybe_unused,
				  int unset __maybe_unused)
3300
{
3301
	struct dirent *script_dirent, *lang_dirent;
3302 3303 3304 3305 3306 3307 3308 3309
	char scripts_path[MAXPATHLEN];
	DIR *scripts_dir, *lang_dir;
	char script_path[MAXPATHLEN];
	char lang_path[MAXPATHLEN];
	struct script_desc *desc;
	char first_half[BUFSIZ];
	char *script_root;

3310
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3311 3312

	scripts_dir = opendir(scripts_path);
3313 3314 3315 3316 3317 3318 3319
	if (!scripts_dir) {
		fprintf(stdout,
			"open(%s) failed.\n"
			"Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",
			scripts_path);
		exit(-1);
	}
3320

3321
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
3322 3323
		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
			  lang_dirent->d_name);
3324 3325 3326 3327
		lang_dir = opendir(lang_path);
		if (!lang_dir)
			continue;

3328 3329
		for_each_script(lang_path, lang_dir, script_dirent) {
			script_root = get_script_root(script_dirent, REPORT_SUFFIX);
3330
			if (script_root) {
3331
				desc = script_desc__findnew(script_root);
3332 3333
				scnprintf(script_path, MAXPATHLEN, "%s/%s",
					  lang_path, script_dirent->d_name);
3334
				read_script_info(desc, script_path);
3335
				free(script_root);
3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350
			}
		}
	}

	fprintf(stdout, "List of available trace scripts:\n");
	list_for_each_entry(desc, &script_descs, node) {
		sprintf(first_half, "%s %s", desc->name,
			desc->args ? desc->args : "");
		fprintf(stdout, "  %-36s %s\n", first_half,
			desc->half_liner ? desc->half_liner : "");
	}

	exit(0);
}

3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378
static int add_dlarg(const struct option *opt __maybe_unused,
		     const char *s, int unset __maybe_unused)
{
	char *arg = strdup(s);
	void *a;

	if (!arg)
		return -1;

	a = realloc(dlargv, sizeof(dlargv[0]) * (dlargc + 1));
	if (!a) {
		free(arg);
		return -1;
	}

	dlargv = a;
	dlargv[dlargc++] = arg;

	return 0;
}

static void free_dlarg(void)
{
	while (dlargc--)
		free(dlargv[dlargc]);
	free(dlargv);
}

3379 3380 3381 3382 3383 3384 3385
/*
 * Some scripts specify the required events in their "xxx-record" file,
 * this function will check if the events in perf.data match those
 * mentioned in the "xxx-record".
 *
 * Fixme: All existing "xxx-record" are all in good formats "-e event ",
 * which is covered well now. And new parsing code should be added to
3386
 * cover the future complex formats like event groups etc.
3387 3388 3389 3390 3391 3392
 */
static int check_ev_match(char *dir_name, char *scriptname,
			struct perf_session *session)
{
	char filename[MAXPATHLEN], evname[128];
	char line[BUFSIZ], *p;
3393
	struct evsel *pos;
3394 3395 3396
	int match, len;
	FILE *fp;

3397
	scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname);
3398 3399 3400 3401 3402 3403

	fp = fopen(filename, "r");
	if (!fp)
		return -1;

	while (fgets(line, sizeof(line), fp)) {
3404
		p = skip_spaces(line);
3405 3406 3407 3408 3409 3410 3411 3412 3413
		if (*p == '#')
			continue;

		while (strlen(p)) {
			p = strstr(p, "-e");
			if (!p)
				break;

			p += 2;
3414
			p = skip_spaces(p);
3415 3416 3417 3418 3419 3420 3421
			len = strcspn(p, " \t");
			if (!len)
				break;

			snprintf(evname, len + 1, "%s", p);

			match = 0;
3422
			evlist__for_each_entry(session->evlist, pos) {
3423
				if (!strcmp(evsel__name(pos), evname)) {
3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439
					match = 1;
					break;
				}
			}

			if (!match) {
				fclose(fp);
				return -1;
			}
		}
	}

	fclose(fp);
	return 0;
}

3440 3441 3442 3443 3444 3445 3446
/*
 * Return -1 if none is found, otherwise the actual scripts number.
 *
 * Currently the only user of this function is the script browser, which
 * will list all statically runnable scripts, select one, execute it and
 * show the output in a perf browser.
 */
3447 3448
int find_scripts(char **scripts_array, char **scripts_path_array, int num,
		 int pathlen)
3449
{
3450
	struct dirent *script_dirent, *lang_dirent;
3451
	char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
3452
	DIR *scripts_dir, *lang_dir;
3453
	struct perf_session *session;
3454
	struct perf_data data = {
3455 3456
		.path = input_name,
		.mode = PERF_DATA_MODE_READ,
3457
	};
3458 3459 3460
	char *temp;
	int i = 0;

3461
	session = perf_session__new(&data, NULL);
3462 3463
	if (IS_ERR(session))
		return PTR_ERR(session);
3464

3465
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3466 3467

	scripts_dir = opendir(scripts_path);
3468 3469
	if (!scripts_dir) {
		perf_session__delete(session);
3470
		return -1;
3471
	}
3472

3473
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
3474 3475
		scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
			  lang_dirent->d_name);
3476
#ifndef HAVE_LIBPERL_SUPPORT
3477 3478 3479
		if (strstr(lang_path, "perl"))
			continue;
#endif
3480
#ifndef HAVE_LIBPYTHON_SUPPORT
3481 3482 3483 3484 3485 3486 3487 3488
		if (strstr(lang_path, "python"))
			continue;
#endif

		lang_dir = opendir(lang_path);
		if (!lang_dir)
			continue;

3489
		for_each_script(lang_path, lang_dir, script_dirent) {
3490
			/* Skip those real time scripts: xxxtop.p[yl] */
3491
			if (strstr(script_dirent->d_name, "top."))
3492
				continue;
3493 3494 3495 3496
			if (i >= num)
				break;
			snprintf(scripts_path_array[i], pathlen, "%s/%s",
				lang_path,
3497 3498
				script_dirent->d_name);
			temp = strchr(script_dirent->d_name, '.');
3499
			snprintf(scripts_array[i],
3500 3501
				(temp - script_dirent->d_name) + 1,
				"%s", script_dirent->d_name);
3502 3503 3504 3505 3506

			if (check_ev_match(lang_path,
					scripts_array[i], session))
				continue;

3507 3508
			i++;
		}
3509
		closedir(lang_dir);
3510 3511
	}

3512 3513
	closedir(scripts_dir);
	perf_session__delete(session);
3514 3515 3516
	return i;
}

3517 3518
static char *get_script_path(const char *script_root, const char *suffix)
{
3519
	struct dirent *script_dirent, *lang_dirent;
3520 3521 3522 3523
	char scripts_path[MAXPATHLEN];
	char script_path[MAXPATHLEN];
	DIR *scripts_dir, *lang_dir;
	char lang_path[MAXPATHLEN];
3524
	char *__script_root;
3525

3526
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3527 3528 3529 3530 3531

	scripts_dir = opendir(scripts_path);
	if (!scripts_dir)
		return NULL;

3532
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
3533 3534
		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
			  lang_dirent->d_name);
3535 3536 3537 3538
		lang_dir = opendir(lang_path);
		if (!lang_dir)
			continue;

3539 3540
		for_each_script(lang_path, lang_dir, script_dirent) {
			__script_root = get_script_root(script_dirent, suffix);
3541 3542
			if (__script_root && !strcmp(script_root, __script_root)) {
				free(__script_root);
3543
				closedir(scripts_dir);
3544 3545
				scnprintf(script_path, MAXPATHLEN, "%s/%s",
					  lang_path, script_dirent->d_name);
3546
				closedir(lang_dir);
3547
				return strdup(script_path);
3548 3549 3550
			}
			free(__script_root);
		}
3551
		closedir(lang_dir);
3552
	}
3553
	closedir(scripts_dir);
3554

3555
	return NULL;
3556 3557
}

3558 3559
static bool is_top_script(const char *script_path)
{
3560
	return ends_with(script_path, "top") != NULL;
3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585
}

static int has_required_arg(char *script_path)
{
	struct script_desc *desc;
	int n_args = 0;
	char *p;

	desc = script_desc__new(NULL);

	if (read_script_info(desc, script_path))
		goto out;

	if (!desc->args)
		goto out;

	for (p = desc->args; *p; p++)
		if (*p == '<')
			n_args++;
out:
	script_desc__delete(desc);

	return n_args;
}

3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598
static int have_cmd(int argc, const char **argv)
{
	char **__argv = malloc(sizeof(const char *) * argc);

	if (!__argv) {
		pr_err("malloc failed\n");
		return -1;
	}

	memcpy(__argv, argv, sizeof(const char *) * argc);
	argc = parse_options(argc, (const char **)__argv, record_options,
			     NULL, PARSE_OPT_STOP_AT_NON_OPTION);
	free(__argv);
3599

3600 3601 3602 3603 3604
	system_wide = (argc == 0);

	return 0;
}

3605 3606 3607
static void script__setup_sample_type(struct perf_script *script)
{
	struct perf_session *session = script->session;
3608
	u64 sample_type = evlist__combined_sample_type(session->evlist);
3609

3610
	callchain_param_setup(sample_type, perf_env__arch(session->machines.host.env));
3611 3612 3613 3614 3615 3616

	if (script->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) {
		pr_warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"
			   "Please apply --call-graph lbr when recording.\n");
		script->stitch_lbr = false;
	}
3617 3618
}

3619 3620
static int process_stat_round_event(struct perf_session *session,
				    union perf_event *event)
3621
{
3622
	struct perf_record_stat_round *round = &event->stat_round;
3623
	struct evsel *counter;
3624

3625
	evlist__for_each_entry(session->evlist, counter) {
3626 3627 3628 3629 3630 3631 3632 3633
		perf_stat_process_counter(&stat_config, counter);
		process_stat(counter, round->time);
	}

	process_stat_interval(round->time);
	return 0;
}

3634 3635
static int process_stat_config_event(struct perf_session *session __maybe_unused,
				     union perf_event *event)
3636 3637
{
	perf_event__read_stat_config(&stat_config, &event->stat_config);
3638 3639 3640 3641 3642 3643 3644

	/*
	 * Aggregation modes are not used since post-processing scripts are
	 * supposed to take care of such requirements
	 */
	stat_config.aggr_mode = AGGR_NONE;

3645 3646 3647
	return 0;
}

3648 3649
static int set_maps(struct perf_script *script)
{
3650
	struct evlist *evlist = script->session->evlist;
3651 3652 3653 3654 3655 3656 3657

	if (!script->cpus || !script->threads)
		return 0;

	if (WARN_ONCE(script->allocated, "stats double allocation\n"))
		return -EINVAL;

3658
	perf_evlist__set_maps(&evlist->core, script->cpus, script->threads);
3659

3660
	if (evlist__alloc_stats(&stat_config, evlist, /*alloc_raw=*/true))
3661 3662 3663 3664 3665 3666 3667
		return -ENOMEM;

	script->allocated = true;
	return 0;
}

static
3668 3669
int process_thread_map_event(struct perf_session *session,
			     union perf_event *event)
3670
{
3671
	struct perf_tool *tool = session->tool;
3672 3673
	struct perf_script *script = container_of(tool, struct perf_script, tool);

3674 3675 3676
	if (dump_trace)
		perf_event__fprintf_thread_map(event, stdout);

3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689
	if (script->threads) {
		pr_warning("Extra thread map event, ignoring.\n");
		return 0;
	}

	script->threads = thread_map__new_event(&event->thread_map);
	if (!script->threads)
		return -ENOMEM;

	return set_maps(script);
}

static
3690 3691
int process_cpu_map_event(struct perf_session *session,
			  union perf_event *event)
3692
{
3693
	struct perf_tool *tool = session->tool;
3694 3695
	struct perf_script *script = container_of(tool, struct perf_script, tool);

3696 3697 3698
	if (dump_trace)
		perf_event__fprintf_cpu_map(event, stdout);

3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710
	if (script->cpus) {
		pr_warning("Extra cpu map event, ignoring.\n");
		return 0;
	}

	script->cpus = cpu_map__new_data(&event->cpu_map.data);
	if (!script->cpus)
		return -ENOMEM;

	return set_maps(script);
}

3711 3712
static int process_feature_event(struct perf_session *session,
				 union perf_event *event)
3713 3714
{
	if (event->feat.feat_id < HEADER_LAST_FEATURE)
3715
		return perf_event__process_feature(session, event);
3716 3717 3718
	return 0;
}

3719
#ifdef HAVE_AUXTRACE_SUPPORT
3720 3721
static int perf_script__process_auxtrace_info(struct perf_session *session,
					      union perf_event *event)
3722
{
3723 3724 3725
	struct perf_tool *tool = session->tool;

	int ret = perf_event__process_auxtrace_info(session, event);
3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738

	if (ret == 0) {
		struct perf_script *script = container_of(tool, struct perf_script, tool);

		ret = perf_script__setup_per_event_dump(script);
	}

	return ret;
}
#else
#define perf_script__process_auxtrace_info 0
#endif

3739 3740 3741 3742 3743 3744
static int parse_insn_trace(const struct option *opt __maybe_unused,
			    const char *str __maybe_unused,
			    int unset __maybe_unused)
{
	parse_output_fields(NULL, "+insn,-event,-period", 0);
	itrace_parse_synth_opts(opt, "i0ns", 0);
3745
	symbol_conf.nanosecs = true;
3746 3747 3748 3749 3750 3751 3752
	return 0;
}

static int parse_xed(const struct option *opt __maybe_unused,
		     const char *str __maybe_unused,
		     int unset __maybe_unused)
{
3753 3754 3755 3756
	if (isatty(1))
		force_pager("xed -F insn: -A -64 | less");
	else
		force_pager("xed -F insn: -A -64");
3757 3758 3759
	return 0;
}

3760 3761 3762 3763 3764 3765
static int parse_call_trace(const struct option *opt __maybe_unused,
			    const char *str __maybe_unused,
			    int unset __maybe_unused)
{
	parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent", 0);
	itrace_parse_synth_opts(opt, "cewp", 0);
3766
	symbol_conf.nanosecs = true;
3767
	symbol_conf.pad_output_len_dso = 50;
3768 3769 3770 3771 3772 3773 3774 3775 3776
	return 0;
}

static int parse_callret_trace(const struct option *opt __maybe_unused,
			    const char *str __maybe_unused,
			    int unset __maybe_unused)
{
	parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent,+flags", 0);
	itrace_parse_synth_opts(opt, "crewp", 0);
3777
	symbol_conf.nanosecs = true;
3778 3779 3780
	return 0;
}

3781
int cmd_script(int argc, const char **argv)
3782 3783
{
	bool show_full_info = false;
3784 3785
	bool header = false;
	bool header_only = false;
3786
	bool script_started = false;
3787
	bool unsorted_dump = false;
3788 3789 3790
	char *rec_script_path = NULL;
	char *rep_script_path = NULL;
	struct perf_session *session;
3791 3792 3793 3794
	struct itrace_synth_opts itrace_synth_opts = {
		.set = false,
		.default_no_sample = true,
	};
3795
	struct utsname uts;
3796
	char *script_path = NULL;
3797
	const char *dlfilter_file = NULL;
3798
	const char **__argv;
3799
	int i, j, err = 0;
3800 3801 3802 3803 3804 3805
	struct perf_script script = {
		.tool = {
			.sample		 = process_sample_event,
			.mmap		 = perf_event__process_mmap,
			.mmap2		 = perf_event__process_mmap2,
			.comm		 = perf_event__process_comm,
3806
			.namespaces	 = perf_event__process_namespaces,
3807
			.cgroup		 = perf_event__process_cgroup,
3808 3809
			.exit		 = perf_event__process_exit,
			.fork		 = perf_event__process_fork,
3810
			.attr		 = process_attr,
3811
			.event_update   = perf_event__process_event_update,
3812
#ifdef HAVE_LIBTRACEEVENT
3813
			.tracing_data	 = perf_event__process_tracing_data,
3814
#endif
3815
			.feature	 = process_feature_event,
3816
			.build_id	 = perf_event__process_build_id,
3817
			.id_index	 = perf_event__process_id_index,
3818
			.auxtrace_info	 = perf_script__process_auxtrace_info,
3819 3820
			.auxtrace	 = perf_event__process_auxtrace,
			.auxtrace_error	 = perf_event__process_auxtrace_error,
3821 3822
			.stat		 = perf_event__process_stat_event,
			.stat_round	 = process_stat_round_event,
3823
			.stat_config	 = process_stat_config_event,
3824 3825
			.thread_map	 = process_thread_map_event,
			.cpu_map	 = process_cpu_map_event,
3826 3827
			.throttle	 = process_throttle_event,
			.unthrottle	 = process_throttle_event,
3828
			.ordered_events	 = true,
3829 3830 3831
			.ordering_requires_timestamps = true,
		},
	};
3832
	struct perf_data data = {
3833 3834
		.mode = PERF_DATA_MODE_READ,
	};
3835
	const struct option options[] = {
3836 3837
	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
		    "dump raw trace in ASCII"),
3838 3839
	OPT_BOOLEAN(0, "dump-unsorted-raw-trace", &unsorted_dump,
		    "dump unsorted raw trace in ASCII"),
3840
	OPT_INCR('v', "verbose", &verbose,
3841
		 "be more verbose (show symbol address, etc)"),
3842
	OPT_BOOLEAN('L', "Latency", &latency_format,
3843
		    "show latency attributes (irqs/preemption disabled, etc)"),
3844 3845
	OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
			   list_available_scripts),
3846 3847
	OPT_CALLBACK_NOOPT(0, "list-dlfilters", NULL, NULL, "list available dlfilters",
			   list_available_dlfilters),
Tom Zanussi's avatar
Tom Zanussi committed
3848 3849 3850 3851
	OPT_CALLBACK('s', "script", NULL, "name",
		     "script file name (lang:script name, script name, or *)",
		     parse_scriptname),
	OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
3852
		   "generate perf-script.xx script in specified language"),
3853
	OPT_STRING(0, "dlfilter", &dlfilter_file, "file", "filter .so file name"),
3854 3855
	OPT_CALLBACK(0, "dlarg", NULL, "argument", "filter argument",
		     add_dlarg),
3856
	OPT_STRING('i', "input", &input_name, "file", "input file name"),
3857 3858
	OPT_BOOLEAN('d', "debug-mode", &debug_mode,
		   "do various checks like samples ordering and lost events"),
3859 3860
	OPT_BOOLEAN(0, "header", &header, "Show data header."),
	OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),
3861 3862 3863 3864 3865 3866
	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
		   "file", "vmlinux pathname"),
	OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
		   "file", "kallsyms pathname"),
	OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
		    "When printing symbols do not display call chain"),
3867 3868 3869
	OPT_CALLBACK(0, "symfs", NULL, "directory",
		     "Look for files with symbols relative to this directory",
		     symbol__config_symfs),
3870
	OPT_CALLBACK('F', "fields", NULL, "str",
3871
		     "comma separated output fields prepend with 'type:'. "
3872
		     "+field to add and -field to remove."
3873
		     "Valid types: hw,sw,trace,raw,synth. "
3874
		     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,dsoff"
3875
		     "addr,symoff,srcline,period,iregs,uregs,brstack,"
3876 3877 3878
		     "brstacksym,flags,data_src,weight,bpf-output,brstackinsn,"
		     "brstackinsnlen,brstackoff,callindent,insn,insnlen,synth,"
		     "phys_addr,metric,misc,srccode,ipc,tod,data_page_size,"
3879
		     "code_page_size,ins_lat,machine_pid,vcpu,cgroup,retire_lat",
3880
		     parse_output_fields),
3881
	OPT_BOOLEAN('a', "all-cpus", &system_wide,
3882
		    "system-wide collection from all CPUs"),
3883 3884
	OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
		   "only consider symbols in these DSOs"),
3885 3886
	OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
		   "only consider these symbols"),
3887 3888
	OPT_INTEGER(0, "addr-range", &symbol_conf.addr_range,
		    "Use with -S to list traced records within address range"),
3889 3890 3891 3892
	OPT_CALLBACK_OPTARG(0, "insn-trace", &itrace_synth_opts, NULL, NULL,
			"Decode instructions from itrace", parse_insn_trace),
	OPT_CALLBACK_OPTARG(0, "xed", NULL, NULL, NULL,
			"Run xed disassembler on output", parse_xed),
3893
	OPT_CALLBACK_OPTARG(0, "call-trace", &itrace_synth_opts, NULL, NULL,
3894
			"Decode calls from itrace", parse_call_trace),
3895 3896
	OPT_CALLBACK_OPTARG(0, "call-ret-trace", &itrace_synth_opts, NULL, NULL,
			"Decode calls and returns from itrace", parse_callret_trace),
3897 3898
	OPT_STRING(0, "graph-function", &symbol_conf.graph_function, "symbol[,symbol...]",
			"Only print symbols and callees with --call-trace/--call-ret-trace"),
3899 3900
	OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]",
		   "Stop display of callgraph at these symbols"),
3901
	OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
3902 3903
	OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
		   "only display events for these comms"),
3904 3905 3906 3907
	OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
		   "only consider symbols in these pids"),
	OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
		   "only consider symbols in these tids"),
3908 3909 3910
	OPT_UINTEGER(0, "max-stack", &scripting_max_stack,
		     "Set the maximum stack depth when parsing the callchain, "
		     "anything beyond the specified depth will be ignored. "
3911
		     "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
3912
	OPT_BOOLEAN(0, "reltime", &reltime, "Show time stamps relative to start"),
3913
	OPT_BOOLEAN(0, "deltatime", &deltatime, "Show time stamps relative to previous event"),
3914 3915
	OPT_BOOLEAN('I', "show-info", &show_full_info,
		    "display extended information from perf.data file"),
3916 3917
	OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
		    "Show the path of [kernel.kallsyms]"),
3918 3919
	OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events,
		    "Show the fork/comm/exit events"),
3920 3921
	OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
		    "Show the mmap events"),
3922 3923
	OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
		    "Show context switch events (if recorded)"),
3924 3925
	OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
		    "Show namespace events (if recorded)"),
3926 3927
	OPT_BOOLEAN('\0', "show-cgroup-events", &script.show_cgroup_events,
		    "Show cgroup events (if recorded)"),
3928 3929
	OPT_BOOLEAN('\0', "show-lost-events", &script.show_lost_events,
		    "Show lost events (if recorded)"),
3930 3931
	OPT_BOOLEAN('\0', "show-round-events", &script.show_round_events,
		    "Show round events (if recorded)"),
3932 3933
	OPT_BOOLEAN('\0', "show-bpf-events", &script.show_bpf_events,
		    "Show bpf related events (if recorded)"),
3934 3935
	OPT_BOOLEAN('\0', "show-text-poke-events", &script.show_text_poke_events,
		    "Show text poke related events (if recorded)"),
3936 3937
	OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
		    "Dump trace output to files named by the monitored events"),
3938
	OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
3939 3940
	OPT_INTEGER(0, "max-blocks", &max_blocks,
		    "Maximum number of code blocks to dump with brstackinsn"),
3941
	OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs,
3942
		    "Use 9 decimal places when displaying time"),
3943
	OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
3944
			    "Instruction Tracing options\n" ITRACE_HELP,
3945
			    itrace_parse_synth_opts),
3946 3947
	OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
			"Show full source file name path for source lines"),
3948 3949 3950 3951
	OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
			"Enable symbol demangling"),
	OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
			"Enable kernel symbol demangling"),
3952 3953
	OPT_STRING(0, "time", &script.time_str, "str",
		   "Time span of interest (start,stop)"),
3954 3955
	OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
		    "Show inline function"),
3956 3957 3958 3959 3960 3961 3962 3963 3964
	OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory",
		   "guest mount directory under which every guest os"
		   " instance has a subdir"),
	OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name,
		   "file", "file saving guest os vmlinux"),
	OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms,
		   "file", "file saving guest os /proc/kallsyms"),
	OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
		   "file", "file saving guest os /proc/modules"),
3965 3966
	OPT_BOOLEAN(0, "guest-code", &symbol_conf.guest_code,
		    "Guest code can be found in hypervisor process"),
3967 3968
	OPT_BOOLEAN('\0', "stitch-lbr", &script.stitch_lbr,
		    "Enable LBR callgraph stitching approach"),
3969
	OPTS_EVSWITCH(&script.evswitch),
3970
	OPT_END()
3971
	};
3972 3973
	const char * const script_subcommands[] = { "record", "report", NULL };
	const char *script_usage[] = {
3974 3975 3976 3977 3978 3979 3980
		"perf script [<options>]",
		"perf script [<options>] record <script> [<record-options>] <command>",
		"perf script [<options>] report <script> [script-args]",
		"perf script [<options>] <script> [<record-options>] <command>",
		"perf script [<options>] <top-script> [script-args]",
		NULL
	};
3981

3982 3983
	perf_set_singlethreaded();

3984 3985
	setup_scripting();

3986
	argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
3987 3988
			     PARSE_OPT_STOP_AT_NON_OPTION);

3989 3990 3991
	if (symbol_conf.guestmount ||
	    symbol_conf.default_guest_vmlinux_name ||
	    symbol_conf.default_guest_kallsyms ||
3992 3993
	    symbol_conf.default_guest_modules ||
	    symbol_conf.guest_code) {
3994 3995 3996 3997 3998 3999
		/*
		 * Enable guest sample processing.
		 */
		perf_guest = true;
	}

4000 4001
	data.path  = input_name;
	data.force = symbol_conf.force;
4002

4003 4004 4005 4006 4007
	if (unsorted_dump) {
		dump_trace = true;
		script.tool.ordered_events = false;
	}

4008 4009 4010
	if (symbol__validate_sym_arguments())
		return -1;

4011
	if (argc > 1 && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
4012 4013
		rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
		if (!rec_script_path)
4014
			return cmd_record(argc, argv);
4015 4016
	}

4017
	if (argc > 1 && strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
4018 4019
		rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
		if (!rep_script_path) {
4020
			fprintf(stderr,
4021
				"Please specify a valid report script"
4022
				"(see 'perf script -l' for listing)\n");
4023 4024 4025 4026
			return -1;
		}
	}

4027 4028 4029 4030 4031 4032 4033
	if (reltime && deltatime) {
		fprintf(stderr,
			"reltime and deltatime - the two don't get along well. "
			"Please limit to --reltime or --deltatime.\n");
		return -1;
	}

4034
	if ((itrace_synth_opts.callchain || itrace_synth_opts.add_callchain) &&
4035 4036 4037
	    itrace_synth_opts.callchain_sz > scripting_max_stack)
		scripting_max_stack = itrace_synth_opts.callchain_sz;

4038
	/* make sure PERF_EXEC_PATH is set for scripts */
4039
	set_argv_exec_path(get_argv_exec_path());
4040

4041
	if (argc && !script_name && !rec_script_path && !rep_script_path) {
4042
		int live_pipe[2];
4043
		int rep_args;
4044 4045
		pid_t pid;

4046 4047 4048 4049
		rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);
		rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);

		if (!rec_script_path && !rep_script_path) {
4050 4051 4052 4053 4054 4055
			script_name = find_script(argv[0]);
			if (script_name) {
				argc -= 1;
				argv += 1;
				goto script_found;
			}
4056 4057
			usage_with_options_msg(script_usage, options,
				"Couldn't find script `%s'\n\n See perf"
4058
				" script -l for available scripts.\n", argv[0]);
4059 4060
		}

4061 4062 4063 4064 4065 4066 4067 4068
		if (is_top_script(argv[0])) {
			rep_args = argc - 1;
		} else {
			int rec_args;

			rep_args = has_required_arg(rep_script_path);
			rec_args = (argc - 1) - rep_args;
			if (rec_args < 0) {
4069 4070
				usage_with_options_msg(script_usage, options,
					"`%s' script requires options."
4071
					"\n\n See perf script -l for available "
4072 4073
					"scripts and options.\n", argv[0]);
			}
4074 4075 4076 4077
		}

		if (pipe(live_pipe) < 0) {
			perror("failed to create pipe");
4078
			return -1;
4079 4080 4081 4082 4083
		}

		pid = fork();
		if (pid < 0) {
			perror("failed to fork");
4084
			return -1;
4085 4086 4087
		}

		if (!pid) {
4088 4089
			j = 0;

4090 4091 4092
			dup2(live_pipe[1], 1);
			close(live_pipe[0]);

4093 4094 4095
			if (is_top_script(argv[0])) {
				system_wide = true;
			} else if (!system_wide) {
4096 4097 4098 4099
				if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
					err = -1;
					goto out;
				}
4100
			}
4101 4102

			__argv = malloc((argc + 6) * sizeof(const char *));
4103 4104 4105 4106 4107
			if (!__argv) {
				pr_err("malloc failed\n");
				err = -ENOMEM;
				goto out;
			}
4108

4109 4110 4111 4112 4113 4114 4115 4116 4117 4118
			__argv[j++] = "/bin/sh";
			__argv[j++] = rec_script_path;
			if (system_wide)
				__argv[j++] = "-a";
			__argv[j++] = "-q";
			__argv[j++] = "-o";
			__argv[j++] = "-";
			for (i = rep_args + 1; i < argc; i++)
				__argv[j++] = argv[i];
			__argv[j++] = NULL;
4119 4120

			execvp("/bin/sh", (char **)__argv);
4121
			free(__argv);
4122 4123 4124 4125 4126 4127
			exit(-1);
		}

		dup2(live_pipe[0], 0);
		close(live_pipe[1]);

4128
		__argv = malloc((argc + 4) * sizeof(const char *));
4129 4130 4131 4132 4133 4134
		if (!__argv) {
			pr_err("malloc failed\n");
			err = -ENOMEM;
			goto out;
		}

4135 4136 4137 4138 4139 4140 4141 4142
		j = 0;
		__argv[j++] = "/bin/sh";
		__argv[j++] = rep_script_path;
		for (i = 1; i < rep_args + 1; i++)
			__argv[j++] = argv[i];
		__argv[j++] = "-i";
		__argv[j++] = "-";
		__argv[j++] = NULL;
4143 4144

		execvp("/bin/sh", (char **)__argv);
4145
		free(__argv);
4146 4147
		exit(-1);
	}
4148
script_found:
4149 4150 4151 4152
	if (rec_script_path)
		script_path = rec_script_path;
	if (rep_script_path)
		script_path = rep_script_path;
4153

4154 4155
	if (script_path) {
		j = 0;
4156

4157 4158
		if (!rec_script_path)
			system_wide = false;
4159 4160 4161 4162 4163 4164
		else if (!system_wide) {
			if (have_cmd(argc - 1, &argv[1]) != 0) {
				err = -1;
				goto out;
			}
		}
4165

4166
		__argv = malloc((argc + 2) * sizeof(const char *));
4167 4168 4169 4170 4171 4172
		if (!__argv) {
			pr_err("malloc failed\n");
			err = -ENOMEM;
			goto out;
		}

4173 4174 4175 4176
		__argv[j++] = "/bin/sh";
		__argv[j++] = script_path;
		if (system_wide)
			__argv[j++] = "-a";
4177
		for (i = 2; i < argc; i++)
4178 4179
			__argv[j++] = argv[i];
		__argv[j++] = NULL;
4180 4181

		execvp("/bin/sh", (char **)__argv);
4182
		free(__argv);
4183 4184
		exit(-1);
	}
Tom Zanussi's avatar
Tom Zanussi committed
4185

4186
	if (dlfilter_file) {
4187
		dlfilter = dlfilter__new(dlfilter_file, dlargc, dlargv);
4188 4189 4190 4191
		if (!dlfilter)
			return -1;
	}

4192
	if (!script_name) {
4193
		setup_pager();
4194 4195
		use_browser = 0;
	}
4196

4197
	session = perf_session__new(&data, &script.tool);
4198 4199
	if (IS_ERR(session))
		return PTR_ERR(session);
4200

4201
	if (header || header_only) {
4202
		script.tool.show_feat_hdr = SHOW_FEAT_HEADER;
4203 4204
		perf_session__fprintf_info(session, stdout, show_full_info);
		if (header_only)
4205
			goto out_delete;
4206
	}
4207 4208
	if (show_full_info)
		script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
4209

4210
	if (symbol__init(&session->header.env) < 0)
4211 4212
		goto out_delete;

4213
	uname(&uts);
4214
	if (data.is_pipe) { /* Assume pipe_mode indicates native_arch */
4215
		native_arch = true;
4216 4217 4218 4219 4220 4221 4222
	} else if (session->header.env.arch) {
		if (!strcmp(uts.machine, session->header.env.arch))
			native_arch = true;
		else if (!strcmp(uts.machine, "x86_64") &&
			 !strcmp(session->header.env.arch, "i386"))
			native_arch = true;
	}
4223

4224
	script.session = session;
4225
	script__setup_sample_type(&script);
4226

4227 4228
	if ((output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT) ||
	    symbol_conf.graph_function)
4229 4230
		itrace_synth_opts.thread_stack = true;

4231 4232
	session->itrace_synth_opts = &itrace_synth_opts;

4233
	if (cpu_list) {
4234 4235 4236
		err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
		if (err < 0)
			goto out_delete;
4237
		itrace_synth_opts.cpu_bitmap = cpu_bitmap;
4238 4239
	}

4240
	if (!no_callchain)
4241 4242 4243 4244
		symbol_conf.use_callchain = true;
	else
		symbol_conf.use_callchain = false;

4245
#ifdef HAVE_LIBTRACEEVENT
4246
	if (session->tevent.pevent &&
4247 4248 4249
	    tep_set_function_resolver(session->tevent.pevent,
				      machine__resolve_kernel_addr,
				      &session->machines.host) < 0) {
4250
		pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
4251 4252
		err = -1;
		goto out_delete;
4253
	}
4254
#endif
Tom Zanussi's avatar
Tom Zanussi committed
4255 4256
	if (generate_script_lang) {
		struct stat perf_stat;
4257 4258
		int input;

4259
		if (output_set_by_user()) {
4260 4261
			fprintf(stderr,
				"custom fields not supported for generated scripts");
4262 4263
			err = -EINVAL;
			goto out_delete;
4264
		}
Tom Zanussi's avatar
Tom Zanussi committed
4265

4266
		input = open(data.path, O_RDONLY);	/* input_name */
Tom Zanussi's avatar
Tom Zanussi committed
4267
		if (input < 0) {
4268
			err = -errno;
Tom Zanussi's avatar
Tom Zanussi committed
4269
			perror("failed to open file");
4270
			goto out_delete;
Tom Zanussi's avatar
Tom Zanussi committed
4271 4272 4273 4274 4275
		}

		err = fstat(input, &perf_stat);
		if (err < 0) {
			perror("failed to stat file");
4276
			goto out_delete;
Tom Zanussi's avatar
Tom Zanussi committed
4277 4278 4279 4280
		}

		if (!perf_stat.st_size) {
			fprintf(stderr, "zero-sized file, nothing to do!\n");
4281
			goto out_delete;
Tom Zanussi's avatar
Tom Zanussi committed
4282 4283 4284 4285 4286
		}

		scripting_ops = script_spec__lookup(generate_script_lang);
		if (!scripting_ops) {
			fprintf(stderr, "invalid language specifier");
4287 4288
			err = -ENOENT;
			goto out_delete;
Tom Zanussi's avatar
Tom Zanussi committed
4289
		}
4290
#ifdef HAVE_LIBTRACEEVENT
4291
		err = scripting_ops->generate_script(session->tevent.pevent,
4292
						     "perf-script");
4293 4294 4295
#else
		err = scripting_ops->generate_script(NULL, "perf-script");
#endif
4296
		goto out_delete;
Tom Zanussi's avatar
Tom Zanussi committed
4297 4298
	}

4299 4300 4301 4302
	err = dlfilter__start(dlfilter, session);
	if (err)
		goto out_delete;

Tom Zanussi's avatar
Tom Zanussi committed
4303
	if (script_name) {
4304
		err = scripting_ops->start_script(script_name, argc, argv, session);
Tom Zanussi's avatar
Tom Zanussi committed
4305
		if (err)
4306
			goto out_delete;
4307
		pr_debug("perf script started with script %s\n\n", script_name);
4308
		script_started = true;
Tom Zanussi's avatar
Tom Zanussi committed
4309 4310
	}

4311 4312 4313

	err = perf_session__check_output_opt(session);
	if (err < 0)
4314
		goto out_delete;
4315

4316
	if (script.time_str) {
4317
		err = perf_time__parse_for_ranges_reltime(script.time_str, session,
4318 4319
						  &script.ptime_range,
						  &script.range_size,
4320 4321
						  &script.range_num,
						  reltime);
4322
		if (err < 0)
4323
			goto out_delete;
4324 4325 4326 4327

		itrace_synth_opts__set_time_range(&itrace_synth_opts,
						  script.ptime_range,
						  script.range_num);
4328 4329
	}

4330 4331 4332
	err = evswitch__init(&script.evswitch, session->evlist, stderr);
	if (err)
		goto out_delete;
4333

4334 4335 4336
	if (zstd_init(&(session->zstd_data), 0) < 0)
		pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");

4337
	err = __cmd_script(&script);
Tom Zanussi's avatar
Tom Zanussi committed
4338

4339 4340
	flush_scripting();

4341
out_delete:
4342 4343
	if (script.ptime_range) {
		itrace_synth_opts__clear_time_range(&itrace_synth_opts);
4344
		zfree(&script.ptime_range);
4345
	}
4346

4347
	zstd_fini(&(session->zstd_data));
4348
	evlist__free_stats(session->evlist);
4349
	perf_session__delete(session);
4350
	perf_script__exit(&script);
4351 4352 4353

	if (script_started)
		cleanup_scripting();
4354
	dlfilter__cleanup(dlfilter);
4355
	free_dlarg();
Tom Zanussi's avatar
Tom Zanussi committed
4356 4357
out:
	return err;
4358
}