builtin-script.c 109.5 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
F
Frederic Weisbecker 已提交
2 3
#include "builtin.h"

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

63
#include <linux/ctype.h>
64

T
Tom Zanussi 已提交
65 66
static char const		*script_name;
static char const		*generate_script_lang;
A
Andi Kleen 已提交
67
static bool			reltime;
68
static bool			deltatime;
A
Andi Kleen 已提交
69
static u64			initial_time;
70
static u64			previous_time;
71
static bool			debug_mode;
72
static u64			last_timestamp;
73
static u64			nr_unordered;
74
static bool			no_callchain;
75
static bool			latency_format;
76
static bool			system_wide;
77
static bool			print_flags;
78 79
static const char		*cpu_list;
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
80
static struct perf_stat_config	stat_config;
81
static int			max_blocks;
82
static bool			native_arch;
83
static struct dlfilter		*dlfilter;
84 85
static int			dlargc;
static char			**dlargv;
T
Tom Zanussi 已提交
86

87
unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
88

89
enum perf_output_field {
90 91 92 93 94 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
	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,
122
	PERF_OUTPUT_TOD             = 1ULL << 32,
K
Kan Liang 已提交
123
	PERF_OUTPUT_DATA_PAGE_SIZE  = 1ULL << 33,
124
	PERF_OUTPUT_CODE_PAGE_SIZE  = 1ULL << 34,
125
	PERF_OUTPUT_INS_LAT         = 1ULL << 35,
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
};

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;
151 152 153 154 155 156 157 158 159 160 161 162 163
};

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},
164
	{.str = "ip",    .field = PERF_OUTPUT_IP},
165
	{.str = "sym",   .field = PERF_OUTPUT_SYM},
166
	{.str = "dso",   .field = PERF_OUTPUT_DSO},
167
	{.str = "addr",  .field = PERF_OUTPUT_ADDR},
168
	{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
169
	{.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
J
Jiri Olsa 已提交
170
	{.str = "period", .field = PERF_OUTPUT_PERIOD},
171
	{.str = "iregs", .field = PERF_OUTPUT_IREGS},
A
Andi Kleen 已提交
172
	{.str = "uregs", .field = PERF_OUTPUT_UREGS},
173 174
	{.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
	{.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
175 176
	{.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},
	{.str = "weight",   .field = PERF_OUTPUT_WEIGHT},
177
	{.str = "bpf-output",   .field = PERF_OUTPUT_BPF_OUTPUT},
178
	{.str = "callindent", .field = PERF_OUTPUT_CALLINDENT},
A
Andi Kleen 已提交
179 180
	{.str = "insn", .field = PERF_OUTPUT_INSN},
	{.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},
181
	{.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
182
	{.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
183
	{.str = "synth", .field = PERF_OUTPUT_SYNTH},
184
	{.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
185
	{.str = "metric", .field = PERF_OUTPUT_METRIC},
186
	{.str = "misc", .field = PERF_OUTPUT_MISC},
A
Andi Kleen 已提交
187
	{.str = "srccode", .field = PERF_OUTPUT_SRCCODE},
188
	{.str = "ipc", .field = PERF_OUTPUT_IPC},
189
	{.str = "tod", .field = PERF_OUTPUT_TOD},
K
Kan Liang 已提交
190
	{.str = "data_page_size", .field = PERF_OUTPUT_DATA_PAGE_SIZE},
191
	{.str = "code_page_size", .field = PERF_OUTPUT_CODE_PAGE_SIZE},
192
	{.str = "ins_lat", .field = PERF_OUTPUT_INS_LAT},
193 194
};

195 196
enum {
	OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,
197
	OUTPUT_TYPE_OTHER,
198 199 200
	OUTPUT_TYPE_MAX
};

201
/* default set to maintain compatibility with current format */
202 203
static struct {
	bool user_set;
204
	bool wildcard_set;
205
	unsigned int print_ip_opts;
206 207
	u64 fields;
	u64 invalid_fields;
208
	u64 user_set_fields;
209
	u64 user_unset_fields;
210
} output[OUTPUT_TYPE_MAX] = {
211 212 213 214 215 216

	[PERF_TYPE_HARDWARE] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
217
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
218 219
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
220

221
		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
222 223 224 225 226 227 228
	},

	[PERF_TYPE_SOFTWARE] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
229
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
230 231 232
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
			      PERF_OUTPUT_BPF_OUTPUT,
233 234 235 236 237 238 239 240 241

		.invalid_fields = PERF_OUTPUT_TRACE,
	},

	[PERF_TYPE_TRACEPOINT] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
				  PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
242
				  PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE
243
	},
244

245 246 247 248 249 250 251 252 253 254 255 256
	[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,
	},

257 258 259 260 261
	[PERF_TYPE_RAW] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
262
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
263 264 265
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
			      PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC |
K
Kan Liang 已提交
266
			      PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR |
267 268
			      PERF_OUTPUT_DATA_PAGE_SIZE | PERF_OUTPUT_CODE_PAGE_SIZE |
			      PERF_OUTPUT_INS_LAT,
269

270
		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
271
	},
272 273 274 275 276 277 278

	[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 |
279 280
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
281

282
		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
283
	},
284 285 286 287 288 289 290

	[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 |
291 292
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_SYNTH,
293 294 295

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

	[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,
	},
308
};
309

310
struct evsel_script {
311 312 313
       char *filename;
       FILE *fp;
       u64  samples;
314 315 316
       /* For metric output */
       u64  val;
       int  gnum;
317 318
};

319
static inline struct evsel_script *evsel_script(struct evsel *evsel)
320
{
321
	return (struct evsel_script *)evsel->priv;
322 323
}

324
static struct evsel_script *evsel_script__new(struct evsel *evsel, struct perf_data *data)
325
{
326
	struct evsel_script *es = zalloc(sizeof(*es));
327 328

	if (es != NULL) {
329
		if (asprintf(&es->filename, "%s.%s.dump", data->file.path, evsel__name(evsel)) < 0)
330 331 332 333 334 335 336 337 338 339 340 341 342 343
			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;
}

344
static void evsel_script__delete(struct evsel_script *es)
345 346 347 348 349 350 351
{
	zfree(&es->filename);
	fclose(es->fp);
	es->fp = NULL;
	free(es);
}

352
static int evsel_script__fprintf(struct evsel_script *es, FILE *fp)
353 354 355 356 357 358 359 360
{
	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);
}

361 362 363 364 365 366
static inline int output_type(unsigned int type)
{
	switch (type) {
	case PERF_TYPE_SYNTH:
		return OUTPUT_TYPE_SYNTH;
	default:
367 368
		if (type < PERF_TYPE_MAX)
			return type;
369
	}
370 371

	return OUTPUT_TYPE_OTHER;
372 373
}

374 375 376
static bool output_set_by_user(void)
{
	int j;
377
	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
378 379 380 381 382
		if (output[j].user_set)
			return true;
	}
	return false;
}
383

384 385 386 387 388 389 390 391 392 393 394 395 396 397
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;
}

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

400 401
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)
402
{
403
	struct perf_event_attr *attr = &evsel->core.attr;
404
	int type = output_type(attr->type);
405 406 407 408 409
	const char *evname;

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

410
	if (output[type].user_set_fields & field) {
411 412
		if (allow_user_set)
			return 0;
413
		evname = evsel__name(evsel);
414 415 416 417 418 419 420 421
		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;
422
	evname = evsel__name(evsel);
423 424 425 426 427 428 429
	pr_debug("Samples for '%s' event do not have %s attribute set. "
		 "Skipping '%s' field.\n",
		 evname, sample_msg, output_field2str(field));

	return 0;
}

430 431
static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
			      enum perf_output_field field)
432
{
433
	return evsel__do_check_stype(evsel, sample_type, sample_msg, field, false);
434 435
}

436
static int evsel__check_attr(struct evsel *evsel, struct perf_session *session)
437
{
438
	struct perf_event_attr *attr = &evsel->core.attr;
439 440
	bool allow_user_set;

441 442 443
	if (perf_header__has_feat(&session->header, HEADER_STAT))
		return 0;

444 445
	allow_user_set = perf_header__has_feat(&session->header,
					       HEADER_AUXTRACE);
446

447
	if (PRINT_FIELD(TRACE) &&
448
	    !perf_session__has_traces(session, "record -R"))
449 450
		return -EINVAL;

451
	if (PRINT_FIELD(IP)) {
452
		if (evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", PERF_OUTPUT_IP))
453 454
			return -EINVAL;
	}
455 456

	if (PRINT_FIELD(ADDR) &&
457
	    evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", PERF_OUTPUT_ADDR, allow_user_set))
458 459
		return -EINVAL;

460
	if (PRINT_FIELD(DATA_SRC) &&
461
	    evsel__check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC", PERF_OUTPUT_DATA_SRC))
462 463 464
		return -EINVAL;

	if (PRINT_FIELD(WEIGHT) &&
465
	    evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT_TYPE, "WEIGHT", PERF_OUTPUT_WEIGHT))
466 467
		return -EINVAL;

468
	if (PRINT_FIELD(SYM) &&
469
	    !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
470
		pr_err("Display of symbols requested but neither sample IP nor "
471
			   "sample address\navailable. Hence, no addresses to convert "
472
		       "to symbols.\n");
473 474
		return -EINVAL;
	}
475 476 477 478 479
	if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
		pr_err("Display of offsets requested but symbol is not"
		       "selected.\n");
		return -EINVAL;
	}
480
	if (PRINT_FIELD(DSO) &&
481
	    !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
482
		pr_err("Display of DSO requested but no address to convert.\n");
483 484
		return -EINVAL;
	}
A
Andi Kleen 已提交
485
	if ((PRINT_FIELD(SRCLINE) || PRINT_FIELD(SRCCODE)) && !PRINT_FIELD(IP)) {
486 487 488 489
		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;
	}
490
	if (PRINT_FIELD(BRSTACKINSN) && !allow_user_set &&
491
	    !(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY)) {
492 493 494 495
		pr_err("Display of branch stack assembler requested, but non all-branch filter set\n"
		       "Hint: run 'perf record -b ...'\n");
		return -EINVAL;
	}
496
	if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
497
	    evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", PERF_OUTPUT_TID|PERF_OUTPUT_PID))
498 499 500
		return -EINVAL;

	if (PRINT_FIELD(TIME) &&
501
	    evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", PERF_OUTPUT_TIME))
502 503 504
		return -EINVAL;

	if (PRINT_FIELD(CPU) &&
505
	    evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU", PERF_OUTPUT_CPU, allow_user_set))
506
		return -EINVAL;
507

508
	if (PRINT_FIELD(IREGS) &&
509
	    evsel__do_check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", PERF_OUTPUT_IREGS, allow_user_set))
510 511
		return -EINVAL;

A
Andi Kleen 已提交
512
	if (PRINT_FIELD(UREGS) &&
513
	    evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS", PERF_OUTPUT_UREGS))
A
Andi Kleen 已提交
514 515
		return -EINVAL;

516
	if (PRINT_FIELD(PHYS_ADDR) &&
517
	    evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", PERF_OUTPUT_PHYS_ADDR))
518 519
		return -EINVAL;

K
Kan Liang 已提交
520 521 522 523
	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;

524 525 526 527
	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;

528 529 530 531
	if (PRINT_FIELD(INS_LAT) &&
	    evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT_STRUCT, "WEIGHT_STRUCT", PERF_OUTPUT_INS_LAT))
		return -EINVAL;

532 533 534
	return 0;
}

535 536
static void set_print_ip_opts(struct perf_event_attr *attr)
{
537
	unsigned int type = output_type(attr->type);
538 539 540

	output[type].print_ip_opts = 0;
	if (PRINT_FIELD(IP))
541
		output[type].print_ip_opts |= EVSEL__PRINT_IP;
542 543

	if (PRINT_FIELD(SYM))
544
		output[type].print_ip_opts |= EVSEL__PRINT_SYM;
545 546

	if (PRINT_FIELD(DSO))
547
		output[type].print_ip_opts |= EVSEL__PRINT_DSO;
548 549

	if (PRINT_FIELD(SYMOFFSET))
550
		output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET;
551 552

	if (PRINT_FIELD(SRCLINE))
553
		output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
554 555
}

556 557 558 559 560 561 562 563 564 565 566 567
static struct evsel *find_first_output_type(struct evlist *evlist,
					    unsigned int type)
{
	struct evsel *evsel;

	evlist__for_each_entry(evlist, evsel) {
		if (output_type(evsel->core.attr.type) == (int)type)
			return evsel;
	}
	return NULL;
}

568 569 570 571 572 573
/*
 * verify all user requested events exist and the samples
 * have the expected data
 */
static int perf_session__check_output_opt(struct perf_session *session)
{
574
	bool tod = false;
575
	unsigned int j;
576
	struct evsel *evsel;
577

578
	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
579
		evsel = find_first_output_type(session->evlist, j);
580 581 582 583 584

		/*
		 * even if fields is set to 0 (ie., show nothing) event must
		 * exist if user explicitly includes it on the command line
		 */
585 586
		if (!evsel && output[j].user_set && !output[j].wildcard_set &&
		    j != OUTPUT_TYPE_SYNTH) {
587
			pr_err("%s events do not exist. "
588
			       "Remove corresponding -F option to proceed.\n",
589 590 591 592 593
			       event_type(j));
			return -1;
		}

		if (evsel && output[j].fields &&
594
			evsel__check_attr(evsel, session))
595
			return -1;
596 597 598 599

		if (evsel == NULL)
			continue;

600
		set_print_ip_opts(&evsel->core.attr);
601
		tod |= output[j].fields & PERF_OUTPUT_TOD;
602 603
	}

604 605
	if (!no_callchain) {
		bool use_callchain = false;
606
		bool not_pipe = false;
607

608
		evlist__for_each_entry(session->evlist, evsel) {
609
			not_pipe = true;
610
			if (evsel__has_callchain(evsel)) {
611 612 613 614
				use_callchain = true;
				break;
			}
		}
615
		if (not_pipe && !use_callchain)
616 617 618
			symbol_conf.use_callchain = false;
	}

619 620 621 622 623 624 625 626
	/*
	 * 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;

627
		evlist__for_each_entry(session->evlist, evsel) {
628
			if (evsel->core.attr.type != j)
629 630
				continue;

631
			if (evsel__has_callchain(evsel)) {
632 633
				output[j].fields |= PERF_OUTPUT_IP;
				output[j].fields |= PERF_OUTPUT_SYM;
634
				output[j].fields |= PERF_OUTPUT_SYMOFFSET;
635
				output[j].fields |= PERF_OUTPUT_DSO;
636
				set_print_ip_opts(&evsel->core.attr);
637 638
				goto out;
			}
639 640 641
		}
	}

642 643 644 645 646
	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;
	}
647
out:
648 649
	return 0;
}
650

651
static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask,
652
				     FILE *fp)
A
Andi Kleen 已提交
653 654
{
	unsigned i = 0, r;
655
	int printed = 0;
A
Andi Kleen 已提交
656 657

	if (!regs || !regs->regs)
658
		return 0;
A
Andi Kleen 已提交
659

660
	printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi);
A
Andi Kleen 已提交
661 662 663

	for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
		u64 val = regs->regs[i++];
664
		printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
A
Andi Kleen 已提交
665
	}
666 667

	return printed;
A
Andi Kleen 已提交
668 669
}

670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
#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;
}

720 721 722 723 724 725 726 727 728 729 730 731 732 733
static int perf_sample__fprintf_iregs(struct perf_sample *sample,
				      struct perf_event_attr *attr, FILE *fp)
{
	return perf_sample__fprintf_regs(&sample->intr_regs,
					 attr->sample_regs_intr, fp);
}

static int perf_sample__fprintf_uregs(struct perf_sample *sample,
				      struct perf_event_attr *attr, FILE *fp)
{
	return perf_sample__fprintf_regs(&sample->user_regs,
					 attr->sample_regs_user, fp);
}

734 735
static int perf_sample__fprintf_start(struct perf_script *script,
				      struct perf_sample *sample,
736
				      struct thread *thread,
737
				      struct evsel *evsel,
738
				      u32 type, FILE *fp)
739
{
740
	struct perf_event_attr *attr = &evsel->core.attr;
741
	unsigned long secs;
742
	unsigned long long nsecs;
743
	int printed = 0;
744
	char tstr[128];
745 746

	if (PRINT_FIELD(COMM)) {
747 748
		const char *comm = thread ? thread__comm_str(thread) : ":-1";

749
		if (latency_format)
750
			printed += fprintf(fp, "%8.8s ", comm);
751
		else if (PRINT_FIELD(IP) && evsel__has_callchain(evsel) && symbol_conf.use_callchain)
752
			printed += fprintf(fp, "%s ", comm);
753
		else
754
			printed += fprintf(fp, "%16s ", comm);
755
	}
756

757
	if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
758
		printed += fprintf(fp, "%5d/%-5d ", sample->pid, sample->tid);
759
	else if (PRINT_FIELD(PID))
760
		printed += fprintf(fp, "%5d ", sample->pid);
761
	else if (PRINT_FIELD(TID))
762
		printed += fprintf(fp, "%5d ", sample->tid);
763 764 765

	if (PRINT_FIELD(CPU)) {
		if (latency_format)
766
			printed += fprintf(fp, "%3d ", sample->cpu);
767
		else
768
			printed += fprintf(fp, "[%03d] ", sample->cpu);
769
	}
770

771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799
	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:
800
			if (has(SWITCH_OUT)) {
801
				ret += fprintf(fp, "S");
802 803 804
				if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT)
					ret += fprintf(fp, "p");
			}
805 806 807 808 809 810 811 812 813 814
		default:
			break;
		}

		#undef has

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

815 816 817 818 819
	if (PRINT_FIELD(TOD)) {
		tod_scnprintf(script, tstr, sizeof(tstr), sample->time);
		printed += fprintf(fp, "%s ", tstr);
	}

820
	if (PRINT_FIELD(TIME)) {
A
Andi Kleen 已提交
821 822 823 824 825
		u64 t = sample->time;
		if (reltime) {
			if (!initial_time)
				initial_time = sample->time;
			t = sample->time - initial_time;
826 827 828 829 830 831 832
		} else if (deltatime) {
			if (previous_time)
				t = sample->time - previous_time;
			else {
				t = 0;
			}
			previous_time = sample->time;
A
Andi Kleen 已提交
833 834
		}
		nsecs = t;
835 836
		secs = nsecs / NSEC_PER_SEC;
		nsecs -= secs * NSEC_PER_SEC;
837

838
		if (symbol_conf.nanosecs)
839
			printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs);
840 841
		else {
			char sample_time[32];
A
Andi Kleen 已提交
842
			timestamp__scnprintf_usec(t, sample_time, sizeof(sample_time));
843
			printed += fprintf(fp, "%12s: ", sample_time);
844
		}
845
	}
846 847

	return printed;
848 849
}

850 851 852 853 854 855 856 857 858
static inline char
mispred_str(struct branch_entry *br)
{
	if (!(br->flags.mispred  || br->flags.predicted))
		return '-';

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

859 860 861
static int perf_sample__fprintf_brstack(struct perf_sample *sample,
					struct thread *thread,
					struct perf_event_attr *attr, FILE *fp)
862 863
{
	struct branch_stack *br = sample->branch_stack;
864
	struct branch_entry *entries = perf_sample__branch_entries(sample);
865 866
	struct addr_location alf, alt;
	u64 i, from, to;
867
	int printed = 0;
868 869

	if (!(br && br->nr))
870
		return 0;
871 872

	for (i = 0; i < br->nr; i++) {
873 874
		from = entries[i].from;
		to   = entries[i].to;
875 876 877 878

		if (PRINT_FIELD(DSO)) {
			memset(&alf, 0, sizeof(alf));
			memset(&alt, 0, sizeof(alt));
879 880
			thread__find_map_fb(thread, sample->cpumode, from, &alf);
			thread__find_map_fb(thread, sample->cpumode, to, &alt);
881 882
		}

883
		printed += fprintf(fp, " 0x%"PRIx64, from);
884
		if (PRINT_FIELD(DSO)) {
885 886 887
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alf.map, fp);
			printed += fprintf(fp, ")");
888 889
		}

890
		printed += fprintf(fp, "/0x%"PRIx64, to);
891
		if (PRINT_FIELD(DSO)) {
892 893 894
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alt.map, fp);
			printed += fprintf(fp, ")");
895 896
		}

897
		printed += fprintf(fp, "/%c/%c/%c/%d ",
898 899 900 901
			mispred_str(entries + i),
			entries[i].flags.in_tx ? 'X' : '-',
			entries[i].flags.abort ? 'A' : '-',
			entries[i].flags.cycles);
902
	}
903 904

	return printed;
905 906
}

907 908 909
static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
					   struct thread *thread,
					   struct perf_event_attr *attr, FILE *fp)
910 911
{
	struct branch_stack *br = sample->branch_stack;
912
	struct branch_entry *entries = perf_sample__branch_entries(sample);
913 914
	struct addr_location alf, alt;
	u64 i, from, to;
915
	int printed = 0;
916 917

	if (!(br && br->nr))
918
		return 0;
919 920 921 922 923

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

		memset(&alf, 0, sizeof(alf));
		memset(&alt, 0, sizeof(alt));
924 925
		from = entries[i].from;
		to   = entries[i].to;
926

927 928
		thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
		thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
929

930
		printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
931
		if (PRINT_FIELD(DSO)) {
932 933 934
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alf.map, fp);
			printed += fprintf(fp, ")");
935
		}
936 937
		printed += fprintf(fp, "%c", '/');
		printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp);
938
		if (PRINT_FIELD(DSO)) {
939 940 941
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alt.map, fp);
			printed += fprintf(fp, ")");
942
		}
943
		printed += fprintf(fp, "/%c/%c/%c/%d ",
944 945 946 947
			mispred_str(entries + i),
			entries[i].flags.in_tx ? 'X' : '-',
			entries[i].flags.abort ? 'A' : '-',
			entries[i].flags.cycles);
948
	}
949 950

	return printed;
951 952
}

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

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

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

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

973
		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
974
		    !alf.map->dso->adjust_symbols)
975 976
			from = map__map_ip(alf.map, from);

977
		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
978
		    !alt.map->dso->adjust_symbols)
979 980
			to = map__map_ip(alt.map, to);

981
		printed += fprintf(fp, " 0x%"PRIx64, from);
982
		if (PRINT_FIELD(DSO)) {
983 984 985
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alf.map, fp);
			printed += fprintf(fp, ")");
986
		}
987
		printed += fprintf(fp, "/0x%"PRIx64, to);
988
		if (PRINT_FIELD(DSO)) {
989 990 991
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alt.map, fp);
			printed += fprintf(fp, ")");
992
		}
993
		printed += fprintf(fp, "/%c/%c/%c/%d ",
994 995 996 997
			mispred_str(entries + i),
			entries[i].flags.in_tx ? 'X' : '-',
			entries[i].flags.abort ? 'A' : '-',
			entries[i].flags.cycles);
998
	}
999 1000

	return printed;
1001
}
1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
#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;

	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)) {
1028
		pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end);
1029 1030 1031 1032 1033 1034
		return -ENXIO;
	}

	memset(&al, 0, sizeof(al));
	if (end - start > MAXBB - MAXINSN) {
		if (last)
1035
			pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end);
1036
		else
1037
			pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start);
1038 1039 1040
		return 0;
	}

1041
	if (!thread__find_map(thread, *cpumode, start, &al) || !al.map->dso) {
1042
		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
1043 1044 1045
		return 0;
	}
	if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) {
1046
		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
		return 0;
	}

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

	offset = al.map->map_ip(al.map, start);
	len = dso__data_read_offset(al.map->dso, machine, offset, (u8 *)buffer,
				    end - start + MAXINSN);

	*is64bit = al.map->dso->is_64_bit;
	if (len <= 0)
1059
		pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
1060 1061 1062 1063
			start, end);
	return len;
}

1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105
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;

	if (!map || !map->dso)
		return 0;
	srcfile = get_srcline_split(map->dso,
				    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;
}

A
Andi Kleen 已提交
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
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;
}

1122 1123
static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
			    struct perf_insn *x, u8 *inbuf, int len,
1124
			    int insn, FILE *fp, int *total_cycles)
1125
{
1126 1127 1128 1129 1130 1131
	int printed = fprintf(fp, "\t%016" PRIx64 "\t%-30s\t#%s%s%s%s", ip,
			      dump_insn(x, ip, inbuf, len, NULL),
			      en->flags.predicted ? " PRED" : "",
			      en->flags.mispred ? " MISPRED" : "",
			      en->flags.in_tx ? " INTX" : "",
			      en->flags.abort ? " ABORT" : "");
1132
	if (en->flags.cycles) {
1133 1134
		*total_cycles += en->flags.cycles;
		printed += fprintf(fp, " %d cycles [%d]", en->flags.cycles, *total_cycles);
1135
		if (insn)
1136
			printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
1137
	}
1138
	return printed + fprintf(fp, "\n");
1139 1140
}

1141 1142 1143
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)
1144 1145
{
	struct addr_location al;
1146
	int off, printed = 0;
1147 1148 1149

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

1150 1151
	thread__find_map(thread, cpumode, addr, &al);

1152
	if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
1153
		return 0;
1154 1155 1156 1157 1158 1159 1160

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

	if (!al.sym)
1161
		return 0;
1162 1163 1164 1165 1166

	if (al.addr < al.sym->end)
		off = al.addr - al.sym->start;
	else
		off = al.addr - al.map->start - al.sym->start;
1167
	printed += fprintf(fp, "\t%s", al.sym->name);
1168
	if (off)
1169 1170
		printed += fprintf(fp, "%+d", off);
	printed += fprintf(fp, ":");
1171
	if (PRINT_FIELD(SRCLINE))
1172 1173
		printed += map__fprintf_srcline(al.map, al.addr, "\t", fp);
	printed += fprintf(fp, "\n");
1174
	*lastsym = al.sym;
1175 1176

	return printed;
1177 1178
}

1179 1180 1181 1182
static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
					    struct thread *thread,
					    struct perf_event_attr *attr,
					    struct machine *machine, FILE *fp)
1183 1184
{
	struct branch_stack *br = sample->branch_stack;
1185
	struct branch_entry *entries = perf_sample__branch_entries(sample);
1186
	u64 start, end;
1187
	int i, insn, len, nr, ilen, printed = 0;
1188 1189 1190 1191
	struct perf_insn x;
	u8 buffer[MAXBB];
	unsigned off;
	struct symbol *lastsym = NULL;
1192
	int total_cycles = 0;
1193 1194

	if (!(br && br->nr))
1195
		return 0;
1196 1197 1198 1199 1200 1201 1202
	nr = br->nr;
	if (max_blocks && nr > max_blocks + 1)
		nr = max_blocks + 1;

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

1203
	printed += fprintf(fp, "%c", '\n');
1204 1205

	/* Handle first from jump, of which we don't know the entry. */
1206 1207
	len = grab_bb(buffer, entries[nr-1].from,
			entries[nr-1].from,
1208 1209
			machine, thread, &x.is64bit, &x.cpumode, false);
	if (len > 0) {
1210
		printed += ip__fprintf_sym(entries[nr - 1].from, thread,
1211
					   x.cpumode, x.cpu, &lastsym, attr, fp);
1212
		printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1],
1213
					    &x, buffer, len, 0, fp, &total_cycles);
A
Andi Kleen 已提交
1214
		if (PRINT_FIELD(SRCCODE))
1215
			printed += print_srccode(thread, x.cpumode, entries[nr - 1].from);
1216 1217 1218 1219
	}

	/* Print all blocks */
	for (i = nr - 2; i >= 0; i--) {
1220
		if (entries[i].from || entries[i].to)
1221
			pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i,
1222 1223 1224 1225
				 entries[i].from,
				 entries[i].to);
		start = entries[i + 1].to;
		end   = entries[i].from;
1226 1227 1228 1229

		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) {
1230
			end = entries[--i].from;
1231 1232 1233 1234 1235 1236 1237
			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;
1238
		for (off = 0; off < (unsigned)len; off += ilen) {
1239 1240
			uint64_t ip = start + off;

1241
			printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
1242
			if (ip == end) {
1243
				printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp,
1244
							    &total_cycles);
A
Andi Kleen 已提交
1245 1246
				if (PRINT_FIELD(SRCCODE))
					printed += print_srccode(thread, x.cpumode, ip);
1247 1248
				break;
			} else {
1249
				ilen = 0;
1250 1251
				printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip,
						   dump_insn(&x, ip, buffer + off, len - off, &ilen));
1252 1253
				if (ilen == 0)
					break;
A
Andi Kleen 已提交
1254 1255
				if (PRINT_FIELD(SRCCODE))
					print_srccode(thread, x.cpumode, ip);
1256 1257 1258
				insn++;
			}
		}
1259
		if (off != end - start)
1260
			printed += fprintf(fp, "\tmismatch of LBR data and executable\n");
1261 1262 1263 1264 1265 1266
	}

	/*
	 * Hit the branch? In this case we are already done, and the target
	 * has not been executed yet.
	 */
1267
	if (entries[0].from == sample->ip)
1268
		goto out;
1269
	if (entries[0].flags.abort)
1270
		goto out;
1271 1272 1273

	/*
	 * Print final block upto sample
1274 1275 1276 1277 1278
	 *
	 * 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.
1279
	 */
1280
	start = entries[0].to;
1281
	end = sample->ip;
1282 1283 1284 1285
	if (end < start) {
		/* Missing jump. Scan 128 bytes for the next branch */
		end = start + 128;
	}
1286
	len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
1287
	printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
1288 1289 1290 1291 1292
	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)
1293 1294
			goto out;
		printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip,
1295
			dump_insn(&x, sample->ip, buffer, len, NULL));
A
Andi Kleen 已提交
1296 1297
		if (PRINT_FIELD(SRCCODE))
			print_srccode(thread, x.cpumode, sample->ip);
1298
		goto out;
1299 1300
	}
	for (off = 0; off <= end - start; off += ilen) {
1301
		ilen = 0;
1302 1303
		printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", start + off,
				   dump_insn(&x, start + off, buffer + off, len - off, &ilen));
1304 1305
		if (ilen == 0)
			break;
1306 1307 1308 1309 1310 1311 1312
		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;
		}
A
Andi Kleen 已提交
1313 1314
		if (PRINT_FIELD(SRCCODE))
			print_srccode(thread, x.cpumode, start + off);
1315
	}
1316 1317
out:
	return printed;
1318
}
1319

1320 1321 1322
static int perf_sample__fprintf_addr(struct perf_sample *sample,
				     struct thread *thread,
				     struct perf_event_attr *attr, FILE *fp)
1323 1324
{
	struct addr_location al;
1325
	int printed = fprintf(fp, "%16" PRIx64, sample->addr);
1326 1327

	if (!sample_addr_correlates_sym(attr))
1328
		goto out;
1329

1330
	thread__resolve(thread, &al, sample);
1331 1332

	if (PRINT_FIELD(SYM)) {
1333
		printed += fprintf(fp, " ");
1334
		if (PRINT_FIELD(SYMOFFSET))
1335
			printed += symbol__fprintf_symname_offs(al.sym, &al, fp);
1336
		else
1337
			printed += symbol__fprintf_symname(al.sym, fp);
1338 1339 1340
	}

	if (PRINT_FIELD(DSO)) {
1341 1342 1343
		printed += fprintf(fp, " (");
		printed += map__fprintf_dsoname(al.map, fp);
		printed += fprintf(fp, ")");
1344
	}
1345 1346
out:
	return printed;
1347 1348
}

1349
static const char *resolve_branch_sym(struct perf_sample *sample,
1350
				      struct evsel *evsel,
1351 1352
				      struct thread *thread,
				      struct addr_location *al,
1353
				      struct addr_location *addr_al,
1354 1355
				      u64 *ip)
{
1356
	struct perf_event_attr *attr = &evsel->core.attr;
1357 1358 1359 1360
	const char *name = NULL;

	if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) {
		if (sample_addr_correlates_sym(attr)) {
1361 1362 1363 1364
			if (!addr_al->thread)
				thread__resolve(thread, addr_al, sample);
			if (addr_al->sym)
				name = addr_al->sym->name;
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378
			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;
}

1379
static int perf_sample__fprintf_callindent(struct perf_sample *sample,
1380
					   struct evsel *evsel,
1381
					   struct thread *thread,
1382 1383 1384
					   struct addr_location *al,
					   struct addr_location *addr_al,
					   FILE *fp)
1385
{
1386
	struct perf_event_attr *attr = &evsel->core.attr;
1387
	size_t depth = thread_stack__depth(thread, sample->cpu);
1388 1389 1390
	const char *name = NULL;
	static int spacing;
	int len = 0;
1391
	int dlen = 0;
1392 1393 1394 1395 1396 1397 1398 1399 1400
	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;

1401
	name = resolve_branch_sym(sample, evsel, thread, al, addr_al, &ip);
1402

1403 1404 1405 1406 1407 1408
	if (PRINT_FIELD(DSO) && !(PRINT_FIELD(IP) || PRINT_FIELD(ADDR))) {
		dlen += fprintf(fp, "(");
		dlen += map__fprintf_dsoname(al->map, fp);
		dlen += fprintf(fp, ")\t");
	}

1409
	if (name)
1410
		len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);
1411
	else if (ip)
1412
		len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip);
1413 1414

	if (len < 0)
1415
		return len;
1416 1417 1418 1419 1420 1421 1422 1423 1424

	/*
	 * 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)
1425 1426
		len += fprintf(fp, "%*s", spacing - len, "");

1427
	return len + dlen;
1428 1429
}

1430 1431 1432 1433 1434 1435
__weak void arch_fetch_insn(struct perf_sample *sample __maybe_unused,
			    struct thread *thread __maybe_unused,
			    struct machine *machine __maybe_unused)
{
}

1436 1437 1438 1439 1440 1441 1442
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);
}

1443 1444 1445 1446
static int perf_sample__fprintf_insn(struct perf_sample *sample,
				     struct perf_event_attr *attr,
				     struct thread *thread,
				     struct machine *machine, FILE *fp)
A
Andi Kleen 已提交
1447
{
1448 1449
	int printed = 0;

1450
	script_fetch_insn(sample, thread, machine);
1451

A
Andi Kleen 已提交
1452
	if (PRINT_FIELD(INSNLEN))
1453
		printed += fprintf(fp, " ilen: %d", sample->insn_len);
1454
	if (PRINT_FIELD(INSN) && sample->insn_len) {
A
Andi Kleen 已提交
1455 1456
		int i;

1457
		printed += fprintf(fp, " insn:");
A
Andi Kleen 已提交
1458
		for (i = 0; i < sample->insn_len; i++)
1459
			printed += fprintf(fp, " %02x", (unsigned char)sample->insn[i]);
A
Andi Kleen 已提交
1460
	}
1461
	if (PRINT_FIELD(BRSTACKINSN))
1462 1463 1464
		printed += perf_sample__fprintf_brstackinsn(sample, thread, attr, machine, fp);

	return printed;
A
Andi Kleen 已提交
1465 1466
}

1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480
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);
}

1481
static int perf_sample__fprintf_bts(struct perf_sample *sample,
1482
				    struct evsel *evsel,
1483 1484
				    struct thread *thread,
				    struct addr_location *al,
1485
				    struct addr_location *addr_al,
1486
				    struct machine *machine, FILE *fp)
1487
{
1488
	struct perf_event_attr *attr = &evsel->core.attr;
1489
	unsigned int type = output_type(attr->type);
1490
	bool print_srcline_last = false;
1491
	int printed = 0;
1492

1493
	if (PRINT_FIELD(CALLINDENT))
1494
		printed += perf_sample__fprintf_callindent(sample, evsel, thread, al, addr_al, fp);
1495

1496 1497
	/* print branch_from information */
	if (PRINT_FIELD(IP)) {
1498
		unsigned int print_opts = output[type].print_ip_opts;
1499
		struct callchain_cursor *cursor = NULL;
1500

1501
		if (symbol_conf.use_callchain && sample->callchain &&
1502
		    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
1503
					      sample, NULL, NULL, scripting_max_stack) == 0)
1504
			cursor = &callchain_cursor;
1505 1506

		if (cursor == NULL) {
1507
			printed += fprintf(fp, " ");
1508
			if (print_opts & EVSEL__PRINT_SRCLINE) {
1509
				print_srcline_last = true;
1510
				print_opts &= ~EVSEL__PRINT_SRCLINE;
1511
			}
1512
		} else
1513
			printed += fprintf(fp, "\n");
1514

1515 1516
		printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor,
					       symbol_conf.bt_stop_list, fp);
1517 1518 1519
	}

	/* print branch_to information */
1520
	if (PRINT_FIELD(ADDR) ||
1521
	    ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
1522
	     !output[type].user_set)) {
1523 1524
		printed += fprintf(fp, " => ");
		printed += perf_sample__fprintf_addr(sample, thread, attr, fp);
1525
	}
1526

1527 1528
	printed += perf_sample__fprintf_ipc(sample, attr, fp);

1529
	if (print_srcline_last)
1530
		printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
A
Andi Kleen 已提交
1531

1532
	printed += perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
A
Andi Kleen 已提交
1533 1534 1535 1536 1537 1538 1539 1540 1541 1542
	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;
1543 1544
}

1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561
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"},
1562 1563
	{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"},
1564 1565 1566
	{0, NULL}
};

1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578
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;
}

1579
int perf_sample__sprintf_flags(u32 flags, char *str, size_t sz)
1580 1581
{
	const char *chars = PERF_IP_FLAG_CHARS;
1582
	const size_t n = strlen(PERF_IP_FLAG_CHARS);
1583 1584
	bool in_tx = flags & PERF_IP_FLAG_IN_TX;
	const char *name = NULL;
1585
	size_t i, pos = 0;
1586

1587 1588
	name = sample_flags_to_name(flags & ~PERF_IP_FLAG_IN_TX);
	if (name)
1589
		return snprintf(str, sz, "%-15s%4s", name, in_tx ? "(x)" : "");
1590 1591 1592 1593

	if (flags & PERF_IP_FLAG_TRACE_BEGIN) {
		name = sample_flags_to_name(flags & ~(PERF_IP_FLAG_IN_TX | PERF_IP_FLAG_TRACE_BEGIN));
		if (name)
1594
			return snprintf(str, sz, "tr strt %-7s%4s", name, in_tx ? "(x)" : "");
1595 1596 1597 1598 1599
	}

	if (flags & PERF_IP_FLAG_TRACE_END) {
		name = sample_flags_to_name(flags & ~(PERF_IP_FLAG_IN_TX | PERF_IP_FLAG_TRACE_END));
		if (name)
1600
			return snprintf(str, sz, "tr end  %-7s%4s", name, in_tx ? "(x)" : "");
1601 1602
	}

1603
	for (i = 0; i < n; i++, flags >>= 1) {
1604
		if ((flags & 1) && pos < sz)
1605 1606 1607
			str[pos++] = chars[i];
	}
	for (; i < 32; i++, flags >>= 1) {
1608
		if ((flags & 1) && pos < sz)
1609 1610
			str[pos++] = '?';
	}
1611 1612 1613 1614 1615 1616 1617 1618 1619
	if (pos < sz)
		str[pos] = 0;

	return pos;
}

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

1621
	perf_sample__sprintf_flags(flags, str, sizeof(str));
1622
	return fprintf(fp, "  %-19s ", str);
1623 1624
}

1625 1626 1627 1628 1629 1630
struct printer_data {
	int line_no;
	bool hit_nul;
	bool is_printable;
};

1631 1632 1633
static int sample__fprintf_bpf_output(enum binary_printer_ops op,
				      unsigned int val,
				      void *extra, FILE *fp)
1634 1635 1636
{
	unsigned char ch = (unsigned char)val;
	struct printer_data *printer_data = extra;
1637
	int printed = 0;
1638 1639 1640

	switch (op) {
	case BINARY_PRINT_DATA_BEGIN:
1641
		printed += fprintf(fp, "\n");
1642 1643
		break;
	case BINARY_PRINT_LINE_BEGIN:
1644
		printed += fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" :
1645 1646 1647
						        "           ");
		break;
	case BINARY_PRINT_ADDR:
1648
		printed += fprintf(fp, " %04x:", val);
1649 1650
		break;
	case BINARY_PRINT_NUM_DATA:
1651
		printed += fprintf(fp, " %02x", val);
1652 1653
		break;
	case BINARY_PRINT_NUM_PAD:
1654
		printed += fprintf(fp, "   ");
1655 1656
		break;
	case BINARY_PRINT_SEP:
1657
		printed += fprintf(fp, "  ");
1658 1659 1660 1661 1662 1663
		break;
	case BINARY_PRINT_CHAR_DATA:
		if (printer_data->hit_nul && ch)
			printer_data->is_printable = false;

		if (!isprint(ch)) {
1664
			printed += fprintf(fp, "%c", '.');
1665 1666 1667 1668 1669 1670 1671 1672 1673

			if (!printer_data->is_printable)
				break;

			if (ch == '\0')
				printer_data->hit_nul = true;
			else
				printer_data->is_printable = false;
		} else {
1674
			printed += fprintf(fp, "%c", ch);
1675 1676 1677
		}
		break;
	case BINARY_PRINT_CHAR_PAD:
1678
		printed += fprintf(fp, " ");
1679 1680
		break;
	case BINARY_PRINT_LINE_END:
1681
		printed += fprintf(fp, "\n");
1682 1683 1684 1685 1686 1687
		printer_data->line_no++;
		break;
	case BINARY_PRINT_DATA_END:
	default:
		break;
	}
1688 1689

	return printed;
1690 1691
}

1692
static int perf_sample__fprintf_bpf_output(struct perf_sample *sample, FILE *fp)
1693 1694 1695
{
	unsigned int nr_bytes = sample->raw_size;
	struct printer_data printer_data = {0, false, true};
1696 1697
	int printed = binary__fprintf(sample->raw_data, nr_bytes, 8,
				      sample__fprintf_bpf_output, &printer_data, fp);
1698 1699

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

	return printed;
1703 1704
}

1705
static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp)
1706 1707
{
	if (len > 0 && len < spacing)
1708 1709 1710
		return fprintf(fp, "%*s", spacing - len, "");

	return 0;
1711 1712
}

1713
static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)
1714
{
1715
	return perf_sample__fprintf_spacing(len, 34, fp);
1716 1717
}

1718
static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp)
1719 1720 1721 1722 1723
{
	struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
	int len;

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

1726
	len = fprintf(fp, " IP: %u payload: %#" PRIx64 " ",
1727
		     data->ip, le64_to_cpu(data->payload));
1728
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1729 1730
}

1731
static int perf_sample__fprintf_synth_mwait(struct perf_sample *sample, FILE *fp)
1732 1733 1734 1735 1736
{
	struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
	int len;

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

1739 1740 1741
	len = fprintf(fp, " hints: %#x extensions: %#x ",
		      data->hints, data->extensions);
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1742 1743
}

1744
static int perf_sample__fprintf_synth_pwre(struct perf_sample *sample, FILE *fp)
1745 1746 1747 1748 1749
{
	struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
	int len;

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

1752 1753 1754
	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);
1755 1756
}

1757
static int perf_sample__fprintf_synth_exstop(struct perf_sample *sample, FILE *fp)
1758 1759 1760 1761 1762
{
	struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
	int len;

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

1765 1766
	len = fprintf(fp, " IP: %u ", data->ip);
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1767 1768
}

1769
static int perf_sample__fprintf_synth_pwrx(struct perf_sample *sample, FILE *fp)
1770 1771 1772 1773 1774
{
	struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
	int len;

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

1777
	len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ",
1778 1779
		     data->deepest_cstate, data->last_cstate,
		     data->wake_reason);
1780
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1781 1782
}

1783
static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp)
1784 1785 1786 1787 1788 1789
{
	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))
1790
		return 0;
1791 1792

	freq = (le32_to_cpu(data->freq) + 500) / 1000;
1793
	len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
1794 1795
	if (data->max_nonturbo) {
		percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
1796
		len += fprintf(fp, "(%3u%%) ", percent);
1797
	}
1798
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1799 1800
}

A
Adrian Hunter 已提交
1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812
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);
}

1813
static int perf_sample__fprintf_synth(struct perf_sample *sample,
1814
				      struct evsel *evsel, FILE *fp)
1815
{
1816
	switch (evsel->core.attr.config) {
1817
	case PERF_SYNTH_INTEL_PTWRITE:
1818
		return perf_sample__fprintf_synth_ptwrite(sample, fp);
1819
	case PERF_SYNTH_INTEL_MWAIT:
1820
		return perf_sample__fprintf_synth_mwait(sample, fp);
1821
	case PERF_SYNTH_INTEL_PWRE:
1822
		return perf_sample__fprintf_synth_pwre(sample, fp);
1823
	case PERF_SYNTH_INTEL_EXSTOP:
1824
		return perf_sample__fprintf_synth_exstop(sample, fp);
1825
	case PERF_SYNTH_INTEL_PWRX:
1826
		return perf_sample__fprintf_synth_pwrx(sample, fp);
1827
	case PERF_SYNTH_INTEL_CBR:
1828
		return perf_sample__fprintf_synth_cbr(sample, fp);
A
Adrian Hunter 已提交
1829 1830
	case PERF_SYNTH_INTEL_PSB:
		return perf_sample__fprintf_synth_psb(sample, fp);
1831 1832 1833
	default:
		break;
	}
1834 1835

	return 0;
1836 1837
}

1838
static int evlist__max_name_len(struct evlist *evlist)
1839
{
1840
	struct evsel *evsel;
1841 1842
	int max = 0;

1843
	evlist__for_each_entry(evlist, evsel) {
1844
		int len = strlen(evsel__name(evsel));
1845 1846 1847 1848 1849 1850 1851

		max = MAX(len, max);
	}

	return max;
}

1852
static int data_src__fprintf(u64 data_src, FILE *fp)
J
Jiri Olsa 已提交
1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865
{
	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;

1866
	return fprintf(fp, "%-*s", maxlen, out);
J
Jiri Olsa 已提交
1867 1868
}

1869 1870 1871
struct metric_ctx {
	struct perf_sample	*sample;
	struct thread		*thread;
1872
	struct evsel	*evsel;
1873 1874 1875
	FILE 			*fp;
};

1876 1877
static void script_print_metric(struct perf_stat_config *config __maybe_unused,
				void *ctx, const char *color,
1878 1879 1880 1881 1882 1883 1884
			        const char *fmt,
			        const char *unit, double val)
{
	struct metric_ctx *mctx = ctx;

	if (!fmt)
		return;
1885
	perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
1886
				   PERF_RECORD_SAMPLE, mctx->fp);
1887 1888 1889 1890 1891 1892 1893 1894
	fputs("\tmetric: ", mctx->fp);
	if (color)
		color_fprintf(mctx->fp, color, fmt, val);
	else
		printf(fmt, val);
	fprintf(mctx->fp, " %s\n", unit);
}

1895 1896
static void script_new_line(struct perf_stat_config *config __maybe_unused,
			    void *ctx)
1897 1898 1899
{
	struct metric_ctx *mctx = ctx;

1900
	perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
1901
				   PERF_RECORD_SAMPLE, mctx->fp);
1902 1903 1904 1905 1906
	fputs("\tmetric: ", mctx->fp);
}

static void perf_sample__fprint_metric(struct perf_script *script,
				       struct thread *thread,
1907
				       struct evsel *evsel,
1908 1909 1910
				       struct perf_sample *sample,
				       FILE *fp)
{
1911
	struct evsel *leader = evsel__leader(evsel);
1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922
	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,
	};
1923
	struct evsel *ev2;
1924 1925 1926
	u64 val;

	if (!evsel->stats)
1927
		evlist__alloc_stats(script->session->evlist, false);
1928
	if (evsel_script(leader)->gnum++ == 0)
1929 1930 1931 1932
		perf_stat__reset_shadow_stats();
	val = sample->period * evsel->scale;
	perf_stat__update_shadow_stats(evsel,
				       val,
1933 1934
				       sample->cpu,
				       &rt_stat);
1935
	evsel_script(evsel)->val = val;
1936 1937
	if (evsel_script(leader)->gnum == leader->core.nr_members) {
		for_each_group_member (ev2, leader) {
1938
			perf_stat__print_shadow_stats(&stat_config, ev2,
1939 1940 1941
						      evsel_script(ev2)->val,
						      sample->cpu,
						      &ctx,
J
Jin Yao 已提交
1942 1943
						      NULL,
						      &rt_stat);
1944
		}
1945
		evsel_script(leader)->gnum = 0;
1946 1947 1948
	}
}

1949
static bool show_event(struct perf_sample *sample,
1950
		       struct evsel *evsel,
1951
		       struct thread *thread,
1952 1953
		       struct addr_location *al,
		       struct addr_location *addr_al)
1954
{
1955
	int depth = thread_stack__depth(thread, sample->cpu);
1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968

	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;
1969
		const char *name = resolve_branch_sym(sample, evsel, thread, al, addr_al,
1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990
				&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;
	}
}

1991
static void process_event(struct perf_script *script,
1992
			  struct perf_sample *sample, struct evsel *evsel,
1993
			  struct addr_location *al,
1994
			  struct addr_location *addr_al,
1995
			  struct machine *machine)
1996
{
1997
	struct thread *thread = al->thread;
1998
	struct perf_event_attr *attr = &evsel->core.attr;
1999
	unsigned int type = output_type(attr->type);
2000
	struct evsel_script *es = evsel->priv;
2001
	FILE *fp = es->fp;
K
Kan Liang 已提交
2002
	char str[PAGE_SIZE_NAME_LEN];
2003

2004
	if (output[type].fields == 0)
2005 2006
		return;

2007 2008
	++es->samples;

2009
	perf_sample__fprintf_start(script, sample, thread, evsel,
2010
				   PERF_RECORD_SAMPLE, fp);
2011

J
Jiri Olsa 已提交
2012
	if (PRINT_FIELD(PERIOD))
2013
		fprintf(fp, "%10" PRIu64 " ", sample->period);
J
Jiri Olsa 已提交
2014

2015
	if (PRINT_FIELD(EVNAME)) {
2016
		const char *evname = evsel__name(evsel);
2017 2018

		if (!script->name_width)
2019
			script->name_width = evlist__max_name_len(script->session->evlist);
2020

2021
		fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]");
2022 2023
	}

2024
	if (print_flags)
2025
		perf_sample__fprintf_flags(sample->flags, fp);
2026

2027
	if (is_bts_event(attr)) {
2028
		perf_sample__fprintf_bts(sample, evsel, thread, al, addr_al, machine, fp);
2029 2030 2031
		return;
	}

2032
	if (PRINT_FIELD(TRACE) && sample->raw_data) {
2033 2034 2035
		event_format__fprintf(evsel->tp_format, sample->cpu,
				      sample->raw_data, sample->raw_size, fp);
	}
2036 2037

	if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
2038
		perf_sample__fprintf_synth(sample, evsel, fp);
2039

2040
	if (PRINT_FIELD(ADDR))
2041
		perf_sample__fprintf_addr(sample, thread, attr, fp);
2042

2043
	if (PRINT_FIELD(DATA_SRC))
2044
		data_src__fprintf(sample->data_src, fp);
2045 2046

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

2049 2050 2051
	if (PRINT_FIELD(INS_LAT))
		fprintf(fp, "%16" PRIu16, sample->ins_lat);

2052
	if (PRINT_FIELD(IP)) {
2053
		struct callchain_cursor *cursor = NULL;
2054

2055 2056 2057
		if (script->stitch_lbr)
			al->thread->lbr_stitch_enable = true;

2058
		if (symbol_conf.use_callchain && sample->callchain &&
2059
		    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
2060
					      sample, NULL, NULL, scripting_max_stack) == 0)
2061
			cursor = &callchain_cursor;
2062

2063
		fputc(cursor ? '\n' : ' ', fp);
2064 2065
		sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor,
				    symbol_conf.bt_stop_list, fp);
2066 2067
	}

2068
	if (PRINT_FIELD(IREGS))
2069
		perf_sample__fprintf_iregs(sample, attr, fp);
2070

A
Andi Kleen 已提交
2071
	if (PRINT_FIELD(UREGS))
2072
		perf_sample__fprintf_uregs(sample, attr, fp);
A
Andi Kleen 已提交
2073

2074
	if (PRINT_FIELD(BRSTACK))
2075
		perf_sample__fprintf_brstack(sample, thread, attr, fp);
2076
	else if (PRINT_FIELD(BRSTACKSYM))
2077
		perf_sample__fprintf_brstacksym(sample, thread, attr, fp);
2078
	else if (PRINT_FIELD(BRSTACKOFF))
2079
		perf_sample__fprintf_brstackoff(sample, thread, attr, fp);
2080

2081
	if (evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
2082 2083
		perf_sample__fprintf_bpf_output(sample, fp);
	perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
2084 2085

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

K
Kan Liang 已提交
2088 2089 2090
	if (PRINT_FIELD(DATA_PAGE_SIZE))
		fprintf(fp, " %s", get_page_size_name(sample->data_page_size, str));

2091 2092 2093
	if (PRINT_FIELD(CODE_PAGE_SIZE))
		fprintf(fp, " %s", get_page_size_name(sample->code_page_size, str));

2094 2095
	perf_sample__fprintf_ipc(sample, attr, fp);

2096
	fprintf(fp, "\n");
2097

A
Andi Kleen 已提交
2098 2099 2100 2101 2102 2103
	if (PRINT_FIELD(SRCCODE)) {
		if (map__fprintf_srccode(al->map, al->addr, stdout,
					 &thread->srccode_state))
			printf("\n");
	}

2104 2105
	if (PRINT_FIELD(METRIC))
		perf_sample__fprint_metric(script, thread, evsel, sample, fp);
2106 2107 2108

	if (verbose)
		fflush(fp);
2109 2110
}

T
Tom Zanussi 已提交
2111 2112
static struct scripting_ops	*scripting_ops;

2113
static void __process_stat(struct evsel *counter, u64 tstamp)
2114
{
2115
	int nthreads = perf_thread_map__nr(counter->core.threads);
2116
	int ncpus = evsel__nr_cpus(counter);
2117 2118 2119
	int cpu, thread;
	static int header_printed;

2120
	if (counter->core.system_wide)
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135
		nthreads = 1;

	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++) {
		for (cpu = 0; cpu < ncpus; cpu++) {
			struct perf_counts_values *counts;

			counts = perf_counts(counter->counts, cpu, thread);

			printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n",
2136
				counter->core.cpus->map[cpu],
2137
				perf_thread_map__pid(counter->core.threads, thread),
2138 2139 2140 2141
				counts->val,
				counts->ena,
				counts->run,
				tstamp,
2142
				evsel__name(counter));
2143 2144 2145 2146
		}
	}
}

2147
static void process_stat(struct evsel *counter, u64 tstamp)
2148 2149 2150
{
	if (scripting_ops && scripting_ops->process_stat)
		scripting_ops->process_stat(&stat_config, counter, tstamp);
2151 2152
	else
		__process_stat(counter, tstamp);
2153 2154 2155 2156 2157 2158 2159 2160
}

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

T
Tom Zanussi 已提交
2161 2162
static void setup_scripting(void)
{
2163
	setup_perl_scripting();
2164
	setup_python_scripting();
T
Tom Zanussi 已提交
2165 2166
}

2167 2168
static int flush_scripting(void)
{
2169
	return scripting_ops ? scripting_ops->flush_script() : 0;
2170 2171
}

T
Tom Zanussi 已提交
2172 2173
static int cleanup_scripting(void)
{
2174
	pr_debug("\nperf script stopped\n");
2175

2176
	return scripting_ops ? scripting_ops->stop_script() : 0;
T
Tom Zanussi 已提交
2177 2178
}

2179 2180
static bool filter_cpu(struct perf_sample *sample)
{
2181
	if (cpu_list && sample->cpu != (u32)-1)
2182 2183 2184 2185
		return !test_bit(sample->cpu, cpu_bitmap);
	return false;
}

2186
static int process_sample_event(struct perf_tool *tool,
2187
				union perf_event *event,
2188
				struct perf_sample *sample,
2189
				struct evsel *evsel,
2190
				struct machine *machine)
F
Frederic Weisbecker 已提交
2191
{
2192
	struct perf_script *scr = container_of(tool, struct perf_script, tool);
2193
	struct addr_location al;
2194
	struct addr_location addr_al;
2195
	int ret = 0;
F
Frederic Weisbecker 已提交
2196

2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207
	/* 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;
	}

2208 2209
	if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num,
					  sample->time)) {
2210
		goto out_put;
2211
	}
2212

2213 2214 2215 2216 2217 2218
	if (debug_mode) {
		if (sample->time < last_timestamp) {
			pr_err("Samples misordered, previous: %" PRIu64
				" this: %" PRIu64 "\n", last_timestamp,
				sample->time);
			nr_unordered++;
2219
		}
2220
		last_timestamp = sample->time;
2221
		goto out_put;
F
Frederic Weisbecker 已提交
2222
	}
2223

2224
	if (filter_cpu(sample))
2225
		goto out_put;
2226

2227
	if (!al.thread && machine__resolve(machine, &al, sample) < 0) {
2228 2229
		pr_err("problem processing %d event, skipping it.\n",
		       event->header.type);
2230 2231
		ret = -1;
		goto out_put;
2232 2233 2234
	}

	if (al.filtered)
2235
		goto out_put;
2236

2237
	if (!show_event(sample, evsel, al.thread, &al, &addr_al))
2238 2239 2240 2241 2242
		goto out_put;

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

2243 2244 2245 2246 2247 2248 2249
	ret = dlfilter__filter_event(dlfilter, event, sample, evsel, machine, &al, &addr_al);
	if (ret) {
		if (ret > 0)
			ret = 0;
		goto out_put;
	}

2250 2251 2252 2253 2254
	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)) {
2255 2256
			if (!addr_al.thread)
				thread__resolve(al.thread, &addr_al, sample);
2257 2258 2259 2260
			addr_al_ptr = &addr_al;
		}
		scripting_ops->process_event(event, sample, evsel, &al, addr_al_ptr);
	} else {
2261
		process_event(scr, sample, evsel, &al, &addr_al, machine);
2262
	}
2263

2264
out_put:
2265 2266
	if (al.thread)
		addr_location__put(&al);
2267
	return ret;
F
Frederic Weisbecker 已提交
2268 2269
}

2270
static int process_attr(struct perf_tool *tool, union perf_event *event,
2271
			struct evlist **pevlist)
2272 2273
{
	struct perf_script *scr = container_of(tool, struct perf_script, tool);
2274
	struct evlist *evlist;
2275
	struct evsel *evsel, *pos;
2276
	u64 sample_type;
2277
	int err;
2278
	static struct evsel_script *es;
2279 2280 2281 2282 2283 2284

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

	evlist = *pevlist;
2285
	evsel = evlist__last(*pevlist);
2286

2287 2288
	if (!evsel->priv) {
		if (scr->per_event_dump) {
2289
			evsel->priv = evsel_script__new(evsel, scr->session->data);
2290 2291 2292 2293 2294 2295 2296 2297 2298
		} else {
			es = zalloc(sizeof(*es));
			if (!es)
				return -ENOMEM;
			es->fp = stdout;
			evsel->priv = es;
		}
	}

2299 2300
	if (evsel->core.attr.type >= PERF_TYPE_MAX &&
	    evsel->core.attr.type != PERF_TYPE_SYNTH)
2301 2302
		return 0;

2303
	evlist__for_each_entry(evlist, pos) {
2304
		if (pos->core.attr.type == evsel->core.attr.type && pos != evsel)
2305 2306 2307
			return 0;
	}

2308
	if (evsel->core.attr.sample_type) {
2309
		err = evsel__check_attr(evsel, scr->session);
2310 2311 2312
		if (err)
			return err;
	}
2313

2314 2315 2316 2317
	/*
	 * Check if we need to enable callchains based
	 * on events sample_type.
	 */
2318
	sample_type = evlist__combined_sample_type(evlist);
2319
	callchain_param_setup(sample_type);
2320

2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332
	/* 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;
2333 2334
	}
	set_print_ip_opts(&evsel->core.attr);
2335
	return 0;
2336 2337
}

2338 2339 2340 2341 2342
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)
2343 2344 2345
{
	struct perf_script *script = container_of(tool, struct perf_script, tool);
	struct perf_session *session = script->session;
2346
	struct evsel *evsel = evlist__id2evsel(session->evlist, sample->id);
2347
	struct thread *thread = NULL;
2348

2349 2350 2351 2352 2353
	if (evsel && !evsel->core.attr.sample_id_all) {
		sample->cpu = 0;
		sample->time = timestamp;
		sample->pid = pid;
		sample->tid = tid;
2354 2355
	}

2356 2357
	if (filter_cpu(sample))
		return 0;
2358

2359 2360 2361
	if (tid != -1)
		thread = machine__findnew_thread(machine, pid, tid);

2362
	if (evsel) {
2363
		perf_sample__fprintf_start(script, sample, thread, evsel,
2364
					   event->header.type, stdout);
2365
	}
2366

2367
	perf_event__fprintf(event, machine, stdout);
2368

2369
	thread__put(thread);
2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390

	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);
2391 2392
}

2393 2394 2395 2396 2397 2398
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)
2399
		return -1;
2400

2401 2402
	return print_event(tool, event, sample, machine, event->namespaces.pid,
			   event->namespaces.tid);
2403 2404
}

2405 2406 2407 2408 2409 2410
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)
2411
		return -1;
2412

2413 2414
	return print_event(tool, event, sample, machine, sample->pid,
			    sample->tid);
2415 2416
}

2417 2418 2419 2420 2421 2422 2423 2424
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;

2425 2426 2427
	return print_event_with_time(tool, event, sample, machine,
				     event->fork.pid, event->fork.tid,
				     event->fork.time);
2428 2429 2430 2431 2432 2433
}
static int process_exit_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
2434 2435 2436
	/* Print before 'exit' deletes anything */
	if (print_event_with_time(tool, event, sample, machine, event->fork.pid,
				  event->fork.tid, event->fork.time))
2437 2438
		return -1;

2439
	return perf_event__process_exit(tool, event, sample, machine);
2440 2441
}

2442 2443 2444 2445 2446 2447 2448 2449
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;

2450 2451
	return print_event(tool, event, sample, machine, event->mmap.pid,
			   event->mmap.tid);
2452 2453 2454 2455 2456 2457 2458 2459 2460 2461
}

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;

2462 2463
	return print_event(tool, event, sample, machine, event->mmap2.pid,
			   event->mmap2.tid);
2464 2465
}

2466 2467 2468 2469 2470 2471 2472 2473 2474 2475
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;

2476 2477 2478 2479 2480 2481
	if (scripting_ops && scripting_ops->process_switch)
		scripting_ops->process_switch(event, sample, machine);

	if (!script->show_switch_events)
		return 0;

2482 2483
	return print_event(tool, event, sample, machine, sample->pid,
			   sample->tid);
2484 2485
}

2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496
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);
}

2497 2498 2499 2500 2501 2502
static int
process_lost_event(struct perf_tool *tool,
		   union perf_event *event,
		   struct perf_sample *sample,
		   struct machine *machine)
{
2503 2504
	return print_event(tool, event, sample, machine, sample->pid,
			   sample->tid);
2505 2506
}

2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517
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;
}

2518 2519 2520 2521 2522 2523
static int
process_finished_round_event(struct perf_tool *tool __maybe_unused,
			     union perf_event *event,
			     struct ordered_events *oe __maybe_unused)

{
2524
	perf_event__fprintf(event, NULL, stdout);
2525 2526 2527
	return 0;
}

2528 2529 2530 2531 2532 2533 2534 2535 2536
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;

2537 2538
	return print_event(tool, event, sample, machine, sample->pid,
			   sample->tid);
2539 2540
}

2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552
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);
}

2553
static void sig_handler(int sig __maybe_unused)
2554 2555 2556 2557
{
	session_done = 1;
}

2558 2559
static void perf_script__fclose_per_event_dump(struct perf_script *script)
{
2560
	struct evlist *evlist = script->session->evlist;
2561
	struct evsel *evsel;
2562 2563 2564 2565

	evlist__for_each_entry(evlist, evsel) {
		if (!evsel->priv)
			break;
2566
		evsel_script__delete(evsel->priv);
2567 2568 2569 2570 2571 2572
		evsel->priv = NULL;
	}
}

static int perf_script__fopen_per_event_dump(struct perf_script *script)
{
2573
	struct evsel *evsel;
2574 2575

	evlist__for_each_entry(script->session->evlist, evsel) {
2576 2577 2578
		/*
		 * Already setup? I.e. we may be called twice in cases like
		 * Intel PT, one for the intel_pt// and dummy events, then
2579
		 * for the evsels synthesized from the auxtrace info.
2580 2581 2582 2583 2584 2585
		 *
		 * Ses perf_script__process_auxtrace_info.
		 */
		if (evsel->priv != NULL)
			continue;

2586
		evsel->priv = evsel_script__new(evsel, script->session->data);
2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599
		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)
{
2600 2601
	struct evsel *evsel;
	static struct evsel_script es_stdout;
2602 2603 2604 2605

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

2606 2607
	es_stdout.fp = stdout;

2608
	evlist__for_each_entry(script->session->evlist, evsel)
2609
		evsel->priv = &es_stdout;
2610 2611 2612 2613

	return 0;
}

2614 2615
static void perf_script__exit_per_event_dump_stats(struct perf_script *script)
{
2616
	struct evsel *evsel;
2617 2618

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

2621 2622
		evsel_script__fprintf(es, stdout);
		evsel_script__delete(es);
2623 2624 2625 2626
		evsel->priv = NULL;
	}
}

2627 2628 2629 2630 2631 2632
static void perf_script__exit(struct perf_script *script)
{
	perf_thread_map__put(script->threads);
	perf_cpu_map__put(script->cpus);
}

2633
static int __cmd_script(struct perf_script *script)
F
Frederic Weisbecker 已提交
2634
{
2635 2636
	int ret;

2637 2638
	signal(SIGINT, sig_handler);

2639 2640
	perf_stat__init_shadow_stats();

2641 2642 2643 2644 2645 2646
	/* 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;
	}
2647 2648 2649 2650
	if (script->show_mmap_events) {
		script->tool.mmap = process_mmap_event;
		script->tool.mmap2 = process_mmap2_event;
	}
2651
	if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch))
2652
		script->tool.context_switch = process_switch_event;
2653 2654
	if (scripting_ops && scripting_ops->process_auxtrace_error)
		script->tool.auxtrace_error = process_auxtrace_error;
2655 2656
	if (script->show_namespace_events)
		script->tool.namespaces = process_namespaces_event;
2657 2658
	if (script->show_cgroup_events)
		script->tool.cgroup = process_cgroup_event;
2659 2660
	if (script->show_lost_events)
		script->tool.lost = process_lost_event;
2661 2662 2663 2664
	if (script->show_round_events) {
		script->tool.ordered_events = false;
		script->tool.finished_round = process_finished_round_event;
	}
2665
	if (script->show_bpf_events) {
2666 2667
		script->tool.ksymbol = process_bpf_events;
		script->tool.bpf     = process_bpf_events;
2668
	}
2669 2670 2671 2672
	if (script->show_text_poke_events) {
		script->tool.ksymbol   = process_bpf_events;
		script->tool.text_poke = process_text_poke_events;
	}
2673

2674 2675 2676 2677 2678
	if (perf_script__setup_per_event_dump(script)) {
		pr_err("Couldn't create the per event dump files\n");
		return -1;
	}

2679
	ret = perf_session__process_events(script->session);
2680

2681
	if (script->per_event_dump)
2682
		perf_script__exit_per_event_dump_stats(script);
2683

2684
	if (debug_mode)
2685
		pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
2686 2687

	return ret;
F
Frederic Weisbecker 已提交
2688 2689
}

T
Tom Zanussi 已提交
2690 2691 2692
struct script_spec {
	struct list_head	node;
	struct scripting_ops	*ops;
2693
	char			spec[];
T
Tom Zanussi 已提交
2694 2695
};

2696
static LIST_HEAD(script_specs);
T
Tom Zanussi 已提交
2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733

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;

2734
	s = script_spec__new(spec, ops);
T
Tom Zanussi 已提交
2735 2736
	if (!s)
		return -1;
2737 2738
	else
		script_spec__add(s);
T
Tom Zanussi 已提交
2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757

	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 "
2758
		"perf script -s [spec:]script.[spec]):\n\n");
T
Tom Zanussi 已提交
2759 2760 2761 2762 2763 2764 2765

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

	fprintf(stderr, "\n");
}

2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796
/* 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);
}

2797 2798
static int parse_scriptname(const struct option *opt __maybe_unused,
			    const char *str, int unset __maybe_unused)
T
Tom Zanussi 已提交
2799 2800 2801 2802 2803
{
	char spec[PATH_MAX];
	const char *script, *ext;
	int len;

2804
	if (strcmp(str, "lang") == 0) {
T
Tom Zanussi 已提交
2805
		list_available_languages();
2806
		exit(0);
T
Tom Zanussi 已提交
2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825
	}

	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;
2826
		ext = strrchr(script, '.');
T
Tom Zanussi 已提交
2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837
		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;
		}
	}

2838 2839 2840
	script_name = find_script(script);
	if (!script_name)
		script_name = strdup(script);
T
Tom Zanussi 已提交
2841 2842 2843 2844

	return 0;
}

2845 2846
static int parse_output_fields(const struct option *opt __maybe_unused,
			    const char *arg, int unset __maybe_unused)
2847
{
2848
	char *tok, *strtok_saveptr = NULL;
2849
	int i, imax = ARRAY_SIZE(all_output_options);
2850
	int j;
2851 2852
	int rc = 0;
	char *str = strdup(arg);
2853
	int type = -1;
2854
	enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;
2855 2856 2857 2858

	if (!str)
		return -ENOMEM;

2859 2860 2861
	/* 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.
2862
	 */
2863 2864 2865 2866 2867 2868 2869 2870 2871 2872
	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;
2873 2874
		else if (!strcmp(str, "raw"))
			type = PERF_TYPE_RAW;
2875 2876
		else if (!strcmp(str, "break"))
			type = PERF_TYPE_BREAKPOINT;
2877 2878
		else if (!strcmp(str, "synth"))
			type = OUTPUT_TYPE_SYNTH;
2879 2880
		else {
			fprintf(stderr, "Invalid event type in field string.\n");
2881 2882
			rc = -EINVAL;
			goto out;
2883 2884 2885 2886 2887 2888
		}

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

2889 2890 2891 2892
		/* Don't override defaults for +- */
		if (strchr(tok, '+') || strchr(tok, '-'))
			goto parse;

2893 2894
		output[type].fields = 0;
		output[type].user_set = true;
2895
		output[type].wildcard_set = false;
2896 2897 2898 2899 2900 2901 2902 2903 2904 2905

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

2906 2907 2908 2909
		/* Don't override defaults for +- */
		if (strchr(str, '+') || strchr(str, '-'))
			goto parse;

2910 2911 2912
		if (output_set_by_user())
			pr_warning("Overriding previous field request for all events.\n");

2913
		for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2914 2915
			output[j].fields = 0;
			output[j].user_set = true;
2916
			output[j].wildcard_set = true;
2917
		}
2918 2919
	}

2920
parse:
2921
	for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937
		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;
		}

2938
		for (i = 0; i < imax; ++i) {
2939
			if (strcmp(tok, all_output_options[i].str) == 0)
2940 2941
				break;
		}
2942
		if (i == imax && strcmp(tok, "flags") == 0) {
Y
Yang Li 已提交
2943
			print_flags = change != REMOVE;
2944 2945
			continue;
		}
2946
		if (i == imax) {
2947
			fprintf(stderr, "Invalid field requested.\n");
2948
			rc = -EINVAL;
2949
			goto out;
2950 2951
		}

2952 2953 2954 2955
		if (type == -1) {
			/* add user option to all events types for
			 * which it is valid
			 */
2956
			for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2957 2958 2959
				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));
2960
				} else {
2961
					if (change == REMOVE) {
2962
						output[j].fields &= ~all_output_options[i].field;
2963
						output[j].user_set_fields &= ~all_output_options[i].field;
2964
						output[j].user_unset_fields |= all_output_options[i].field;
2965
					} else {
2966
						output[j].fields |= all_output_options[i].field;
2967
						output[j].user_set_fields |= all_output_options[i].field;
2968
						output[j].user_unset_fields &= ~all_output_options[i].field;
2969
					}
2970 2971
					output[j].user_set = true;
					output[j].wildcard_set = true;
2972
				}
2973 2974 2975 2976 2977 2978 2979 2980 2981
			}
		} 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;
			}
2982 2983 2984 2985
			if (change == REMOVE)
				output[type].fields &= ~all_output_options[i].field;
			else
				output[type].fields |= all_output_options[i].field;
2986 2987
			output[type].user_set = true;
			output[type].wildcard_set = true;
2988
		}
2989 2990
	}

2991 2992 2993 2994 2995 2996
	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));
		}
	}
2997
	goto out;
2998

2999 3000 3001
out_badmix:
	fprintf(stderr, "Cannot mix +-field with overridden fields\n");
	rc = -EINVAL;
3002
out:
3003 3004 3005 3006
	free(str);
	return rc;
}

3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019
#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)))
3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031


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

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

3032
static LIST_HEAD(script_descs);
3033 3034 3035 3036 3037

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

3038
	if (s != NULL && name)
3039 3040 3041 3042 3043 3044 3045
		s->name = strdup(name);

	return s;
}

static void script_desc__delete(struct script_desc *s)
{
3046 3047 3048
	zfree(&s->name);
	zfree(&s->half_liner);
	zfree(&s->args);
3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075
	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)
3076
		return NULL;
3077 3078 3079 3080 3081 3082

	script_desc__add(s);

	return s;
}

3083
static const char *ends_with(const char *str, const char *suffix)
3084 3085
{
	size_t suffix_len = strlen(suffix);
3086
	const char *p = str;
3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106

	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)) {
3107
		p = skip_spaces(line);
3108 3109 3110 3111 3112 3113 3114 3115
		if (strlen(p) == 0)
			continue;
		if (*p != '#')
			continue;
		p++;
		if (strlen(p) && *p == '!')
			continue;

3116
		p = skip_spaces(p);
3117 3118 3119 3120 3121
		if (strlen(p) && p[strlen(p) - 1] == '\n')
			p[strlen(p) - 1] = '\0';

		if (!strncmp(p, "description:", strlen("description:"))) {
			p += strlen("description:");
3122
			desc->half_liner = strdup(skip_spaces(p));
3123 3124 3125 3126 3127
			continue;
		}

		if (!strncmp(p, "args:", strlen("args:"))) {
			p += strlen("args:");
3128
			desc->args = strdup(skip_spaces(p));
3129 3130 3131 3132 3133 3134 3135 3136 3137
			continue;
		}
	}

	fclose(fp);

	return 0;
}

3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155
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;
}

3156 3157 3158
static int list_available_scripts(const struct option *opt __maybe_unused,
				  const char *s __maybe_unused,
				  int unset __maybe_unused)
3159
{
3160
	struct dirent *script_dirent, *lang_dirent;
3161 3162 3163 3164 3165 3166 3167 3168
	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;

3169
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3170 3171

	scripts_dir = opendir(scripts_path);
3172 3173 3174 3175 3176 3177 3178
	if (!scripts_dir) {
		fprintf(stdout,
			"open(%s) failed.\n"
			"Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",
			scripts_path);
		exit(-1);
	}
3179

3180
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
3181 3182
		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
			  lang_dirent->d_name);
3183 3184 3185 3186
		lang_dir = opendir(lang_path);
		if (!lang_dir)
			continue;

3187 3188
		for_each_script(lang_path, lang_dir, script_dirent) {
			script_root = get_script_root(script_dirent, REPORT_SUFFIX);
3189
			if (script_root) {
3190
				desc = script_desc__findnew(script_root);
3191 3192
				scnprintf(script_path, MAXPATHLEN, "%s/%s",
					  lang_path, script_dirent->d_name);
3193
				read_script_info(desc, script_path);
3194
				free(script_root);
3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209
			}
		}
	}

	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);
}

3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237
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);
}

3238 3239 3240 3241 3242 3243 3244
/*
 * 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
3245
 * cover the future complex formats like event groups etc.
3246 3247 3248 3249 3250 3251
 */
static int check_ev_match(char *dir_name, char *scriptname,
			struct perf_session *session)
{
	char filename[MAXPATHLEN], evname[128];
	char line[BUFSIZ], *p;
3252
	struct evsel *pos;
3253 3254 3255
	int match, len;
	FILE *fp;

3256
	scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname);
3257 3258 3259 3260 3261 3262

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

	while (fgets(line, sizeof(line), fp)) {
3263
		p = skip_spaces(line);
3264 3265 3266 3267 3268 3269 3270 3271 3272
		if (*p == '#')
			continue;

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

			p += 2;
3273
			p = skip_spaces(p);
3274 3275 3276 3277 3278 3279 3280
			len = strcspn(p, " \t");
			if (!len)
				break;

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

			match = 0;
3281
			evlist__for_each_entry(session->evlist, pos) {
3282
				if (!strcmp(evsel__name(pos), evname)) {
3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298
					match = 1;
					break;
				}
			}

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

	fclose(fp);
	return 0;
}

3299 3300 3301 3302 3303 3304 3305
/*
 * 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.
 */
3306 3307
int find_scripts(char **scripts_array, char **scripts_path_array, int num,
		 int pathlen)
3308
{
3309
	struct dirent *script_dirent, *lang_dirent;
3310
	char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
3311
	DIR *scripts_dir, *lang_dir;
3312
	struct perf_session *session;
3313
	struct perf_data data = {
J
Jiri Olsa 已提交
3314 3315
		.path = input_name,
		.mode = PERF_DATA_MODE_READ,
3316
	};
3317 3318 3319
	char *temp;
	int i = 0;

3320
	session = perf_session__new(&data, NULL);
3321 3322
	if (IS_ERR(session))
		return PTR_ERR(session);
3323

3324
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3325 3326

	scripts_dir = opendir(scripts_path);
3327 3328
	if (!scripts_dir) {
		perf_session__delete(session);
3329
		return -1;
3330
	}
3331

3332
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
3333 3334
		scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
			  lang_dirent->d_name);
3335
#ifndef HAVE_LIBPERL_SUPPORT
3336 3337 3338
		if (strstr(lang_path, "perl"))
			continue;
#endif
3339
#ifndef HAVE_LIBPYTHON_SUPPORT
3340 3341 3342 3343 3344 3345 3346 3347
		if (strstr(lang_path, "python"))
			continue;
#endif

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

3348
		for_each_script(lang_path, lang_dir, script_dirent) {
3349
			/* Skip those real time scripts: xxxtop.p[yl] */
3350
			if (strstr(script_dirent->d_name, "top."))
3351
				continue;
3352 3353 3354 3355
			if (i >= num)
				break;
			snprintf(scripts_path_array[i], pathlen, "%s/%s",
				lang_path,
3356 3357
				script_dirent->d_name);
			temp = strchr(script_dirent->d_name, '.');
3358
			snprintf(scripts_array[i],
3359 3360
				(temp - script_dirent->d_name) + 1,
				"%s", script_dirent->d_name);
3361 3362 3363 3364 3365

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

3366 3367
			i++;
		}
3368
		closedir(lang_dir);
3369 3370
	}

3371 3372
	closedir(scripts_dir);
	perf_session__delete(session);
3373 3374 3375
	return i;
}

3376 3377
static char *get_script_path(const char *script_root, const char *suffix)
{
3378
	struct dirent *script_dirent, *lang_dirent;
3379 3380 3381 3382
	char scripts_path[MAXPATHLEN];
	char script_path[MAXPATHLEN];
	DIR *scripts_dir, *lang_dir;
	char lang_path[MAXPATHLEN];
3383
	char *__script_root;
3384

3385
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3386 3387 3388 3389 3390

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

3391
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
3392 3393
		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
			  lang_dirent->d_name);
3394 3395 3396 3397
		lang_dir = opendir(lang_path);
		if (!lang_dir)
			continue;

3398 3399
		for_each_script(lang_path, lang_dir, script_dirent) {
			__script_root = get_script_root(script_dirent, suffix);
3400 3401
			if (__script_root && !strcmp(script_root, __script_root)) {
				free(__script_root);
3402
				closedir(scripts_dir);
3403 3404
				scnprintf(script_path, MAXPATHLEN, "%s/%s",
					  lang_path, script_dirent->d_name);
3405
				closedir(lang_dir);
3406
				return strdup(script_path);
3407 3408 3409
			}
			free(__script_root);
		}
3410
		closedir(lang_dir);
3411
	}
3412
	closedir(scripts_dir);
3413

3414
	return NULL;
3415 3416
}

3417 3418
static bool is_top_script(const char *script_path)
{
Y
Yang Li 已提交
3419
	return ends_with(script_path, "top") != NULL;
3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444
}

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;
}

3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457
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);
F
Frederic Weisbecker 已提交
3458

3459 3460 3461 3462 3463
	system_wide = (argc == 0);

	return 0;
}

3464 3465 3466
static void script__setup_sample_type(struct perf_script *script)
{
	struct perf_session *session = script->session;
3467
	u64 sample_type = evlist__combined_sample_type(session->evlist);
3468 3469 3470

	if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
		if ((sample_type & PERF_SAMPLE_REGS_USER) &&
3471
		    (sample_type & PERF_SAMPLE_STACK_USER)) {
3472
			callchain_param.record_mode = CALLCHAIN_DWARF;
3473 3474
			dwarf_callchain_users = true;
		} else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
3475 3476 3477 3478
			callchain_param.record_mode = CALLCHAIN_LBR;
		else
			callchain_param.record_mode = CALLCHAIN_FP;
	}
3479 3480 3481 3482 3483 3484

	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;
	}
3485 3486
}

3487 3488
static int process_stat_round_event(struct perf_session *session,
				    union perf_event *event)
3489
{
3490
	struct perf_record_stat_round *round = &event->stat_round;
3491
	struct evsel *counter;
3492

3493
	evlist__for_each_entry(session->evlist, counter) {
3494 3495 3496 3497 3498 3499 3500 3501
		perf_stat_process_counter(&stat_config, counter);
		process_stat(counter, round->time);
	}

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

3502 3503
static int process_stat_config_event(struct perf_session *session __maybe_unused,
				     union perf_event *event)
3504 3505 3506 3507 3508
{
	perf_event__read_stat_config(&stat_config, &event->stat_config);
	return 0;
}

3509 3510
static int set_maps(struct perf_script *script)
{
3511
	struct evlist *evlist = script->session->evlist;
3512 3513 3514 3515 3516 3517 3518

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

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

3519
	perf_evlist__set_maps(&evlist->core, script->cpus, script->threads);
3520

3521
	if (evlist__alloc_stats(evlist, true))
3522 3523 3524 3525 3526 3527 3528
		return -ENOMEM;

	script->allocated = true;
	return 0;
}

static
3529 3530
int process_thread_map_event(struct perf_session *session,
			     union perf_event *event)
3531
{
3532
	struct perf_tool *tool = session->tool;
3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547
	struct perf_script *script = container_of(tool, struct perf_script, tool);

	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
3548 3549
int process_cpu_map_event(struct perf_session *session,
			  union perf_event *event)
3550
{
3551
	struct perf_tool *tool = session->tool;
3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565
	struct perf_script *script = container_of(tool, struct perf_script, tool);

	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);
}

3566 3567
static int process_feature_event(struct perf_session *session,
				 union perf_event *event)
3568 3569
{
	if (event->feat.feat_id < HEADER_LAST_FEATURE)
3570
		return perf_event__process_feature(session, event);
3571 3572 3573
	return 0;
}

3574
#ifdef HAVE_AUXTRACE_SUPPORT
3575 3576
static int perf_script__process_auxtrace_info(struct perf_session *session,
					      union perf_event *event)
3577
{
3578 3579 3580
	struct perf_tool *tool = session->tool;

	int ret = perf_event__process_auxtrace_info(session, event);
3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593

	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

3594 3595 3596 3597 3598 3599
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);
3600
	symbol_conf.nanosecs = true;
3601 3602 3603 3604 3605 3606 3607
	return 0;
}

static int parse_xed(const struct option *opt __maybe_unused,
		     const char *str __maybe_unused,
		     int unset __maybe_unused)
{
3608 3609 3610 3611
	if (isatty(1))
		force_pager("xed -F insn: -A -64 | less");
	else
		force_pager("xed -F insn: -A -64");
3612 3613 3614
	return 0;
}

3615 3616 3617 3618 3619 3620
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);
3621
	symbol_conf.nanosecs = true;
3622
	symbol_conf.pad_output_len_dso = 50;
3623 3624 3625 3626 3627 3628 3629 3630 3631
	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);
3632
	symbol_conf.nanosecs = true;
3633 3634 3635
	return 0;
}

3636
int cmd_script(int argc, const char **argv)
3637 3638
{
	bool show_full_info = false;
3639 3640
	bool header = false;
	bool header_only = false;
3641
	bool script_started = false;
3642 3643 3644
	char *rec_script_path = NULL;
	char *rep_script_path = NULL;
	struct perf_session *session;
3645 3646 3647 3648
	struct itrace_synth_opts itrace_synth_opts = {
		.set = false,
		.default_no_sample = true,
	};
3649
	struct utsname uts;
3650
	char *script_path = NULL;
3651
	const char *dlfilter_file = NULL;
3652
	const char **__argv;
3653
	int i, j, err = 0;
3654 3655 3656 3657 3658 3659
	struct perf_script script = {
		.tool = {
			.sample		 = process_sample_event,
			.mmap		 = perf_event__process_mmap,
			.mmap2		 = perf_event__process_mmap2,
			.comm		 = perf_event__process_comm,
3660
			.namespaces	 = perf_event__process_namespaces,
3661
			.cgroup		 = perf_event__process_cgroup,
3662 3663
			.exit		 = perf_event__process_exit,
			.fork		 = perf_event__process_fork,
3664
			.attr		 = process_attr,
3665
			.event_update   = perf_event__process_event_update,
3666
			.tracing_data	 = perf_event__process_tracing_data,
3667
			.feature	 = process_feature_event,
3668
			.build_id	 = perf_event__process_build_id,
3669
			.id_index	 = perf_event__process_id_index,
3670
			.auxtrace_info	 = perf_script__process_auxtrace_info,
3671 3672
			.auxtrace	 = perf_event__process_auxtrace,
			.auxtrace_error	 = perf_event__process_auxtrace_error,
3673 3674
			.stat		 = perf_event__process_stat_event,
			.stat_round	 = process_stat_round_event,
3675
			.stat_config	 = process_stat_config_event,
3676 3677
			.thread_map	 = process_thread_map_event,
			.cpu_map	 = process_cpu_map_event,
3678 3679
			.throttle	 = process_throttle_event,
			.unthrottle	 = process_throttle_event,
3680
			.ordered_events	 = true,
3681 3682 3683
			.ordering_requires_timestamps = true,
		},
	};
3684
	struct perf_data data = {
3685 3686
		.mode = PERF_DATA_MODE_READ,
	};
3687
	const struct option options[] = {
F
Frederic Weisbecker 已提交
3688 3689
	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
		    "dump raw trace in ASCII"),
3690
	OPT_INCR('v', "verbose", &verbose,
3691
		 "be more verbose (show symbol address, etc)"),
3692
	OPT_BOOLEAN('L', "Latency", &latency_format,
3693
		    "show latency attributes (irqs/preemption disabled, etc)"),
3694 3695
	OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
			   list_available_scripts),
3696 3697
	OPT_CALLBACK_NOOPT(0, "list-dlfilters", NULL, NULL, "list available dlfilters",
			   list_available_dlfilters),
T
Tom Zanussi 已提交
3698 3699 3700 3701
	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",
3702
		   "generate perf-script.xx script in specified language"),
3703
	OPT_STRING(0, "dlfilter", &dlfilter_file, "file", "filter .so file name"),
3704 3705
	OPT_CALLBACK(0, "dlarg", NULL, "argument", "filter argument",
		     add_dlarg),
3706
	OPT_STRING('i', "input", &input_name, "file", "input file name"),
3707 3708
	OPT_BOOLEAN('d', "debug-mode", &debug_mode,
		   "do various checks like samples ordering and lost events"),
3709 3710
	OPT_BOOLEAN(0, "header", &header, "Show data header."),
	OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),
3711 3712 3713 3714 3715 3716
	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"),
3717 3718 3719
	OPT_CALLBACK(0, "symfs", NULL, "directory",
		     "Look for files with symbols relative to this directory",
		     symbol__config_symfs),
3720
	OPT_CALLBACK('F', "fields", NULL, "str",
3721
		     "comma separated output fields prepend with 'type:'. "
3722
		     "+field to add and -field to remove."
3723
		     "Valid types: hw,sw,trace,raw,synth. "
3724
		     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
3725 3726
		     "addr,symoff,srcline,period,iregs,uregs,brstack,"
		     "brstacksym,flags,bpf-output,brstackinsn,brstackoff,"
K
Kan Liang 已提交
3727
		     "callindent,insn,insnlen,synth,phys_addr,metric,misc,ipc,tod,"
3728
		     "data_page_size,code_page_size,ins_lat",
3729
		     parse_output_fields),
3730
	OPT_BOOLEAN('a', "all-cpus", &system_wide,
3731
		    "system-wide collection from all CPUs"),
3732 3733
	OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
		   "only consider symbols in these DSOs"),
3734 3735
	OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
		   "only consider these symbols"),
3736 3737
	OPT_INTEGER(0, "addr-range", &symbol_conf.addr_range,
		    "Use with -S to list traced records within address range"),
3738 3739 3740 3741
	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),
3742 3743 3744 3745
	OPT_CALLBACK_OPTARG(0, "call-trace", &itrace_synth_opts, NULL, NULL,
			"Decode calls from from itrace", parse_call_trace),
	OPT_CALLBACK_OPTARG(0, "call-ret-trace", &itrace_synth_opts, NULL, NULL,
			"Decode calls and returns from itrace", parse_callret_trace),
3746 3747
	OPT_STRING(0, "graph-function", &symbol_conf.graph_function, "symbol[,symbol...]",
			"Only print symbols and callees with --call-trace/--call-ret-trace"),
3748 3749
	OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]",
		   "Stop display of callgraph at these symbols"),
3750
	OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
3751 3752
	OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
		   "only display events for these comms"),
3753 3754 3755 3756
	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"),
3757 3758 3759
	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. "
3760
		     "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
A
Andi Kleen 已提交
3761
	OPT_BOOLEAN(0, "reltime", &reltime, "Show time stamps relative to start"),
3762
	OPT_BOOLEAN(0, "deltatime", &deltatime, "Show time stamps relative to previous event"),
3763 3764
	OPT_BOOLEAN('I', "show-info", &show_full_info,
		    "display extended information from perf.data file"),
3765 3766
	OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
		    "Show the path of [kernel.kallsyms]"),
3767 3768
	OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events,
		    "Show the fork/comm/exit events"),
3769 3770
	OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
		    "Show the mmap events"),
3771 3772
	OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
		    "Show context switch events (if recorded)"),
3773 3774
	OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
		    "Show namespace events (if recorded)"),
3775 3776
	OPT_BOOLEAN('\0', "show-cgroup-events", &script.show_cgroup_events,
		    "Show cgroup events (if recorded)"),
3777 3778
	OPT_BOOLEAN('\0', "show-lost-events", &script.show_lost_events,
		    "Show lost events (if recorded)"),
3779 3780
	OPT_BOOLEAN('\0', "show-round-events", &script.show_round_events,
		    "Show round events (if recorded)"),
3781 3782
	OPT_BOOLEAN('\0', "show-bpf-events", &script.show_bpf_events,
		    "Show bpf related events (if recorded)"),
3783 3784
	OPT_BOOLEAN('\0', "show-text-poke-events", &script.show_text_poke_events,
		    "Show text poke related events (if recorded)"),
3785 3786
	OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
		    "Dump trace output to files named by the monitored events"),
3787
	OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
3788 3789
	OPT_INTEGER(0, "max-blocks", &max_blocks,
		    "Maximum number of code blocks to dump with brstackinsn"),
3790
	OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs,
3791
		    "Use 9 decimal places when displaying time"),
3792
	OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
3793
			    "Instruction Tracing options\n" ITRACE_HELP,
3794
			    itrace_parse_synth_opts),
3795 3796
	OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
			"Show full source file name path for source lines"),
3797 3798 3799 3800
	OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
			"Enable symbol demangling"),
	OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
			"Enable kernel symbol demangling"),
3801 3802
	OPT_STRING(0, "time", &script.time_str, "str",
		   "Time span of interest (start,stop)"),
3803 3804
	OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
		    "Show inline function"),
3805 3806 3807 3808 3809 3810 3811 3812 3813
	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"),
3814 3815
	OPT_BOOLEAN('\0', "stitch-lbr", &script.stitch_lbr,
		    "Enable LBR callgraph stitching approach"),
3816
	OPTS_EVSWITCH(&script.evswitch),
3817
	OPT_END()
3818
	};
3819 3820
	const char * const script_subcommands[] = { "record", "report", NULL };
	const char *script_usage[] = {
3821 3822 3823 3824 3825 3826 3827
		"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
	};
3828

3829 3830
	perf_set_singlethreaded();

3831 3832
	setup_scripting();

3833
	argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
3834 3835
			     PARSE_OPT_STOP_AT_NON_OPTION);

3836 3837 3838 3839 3840 3841 3842 3843 3844 3845
	if (symbol_conf.guestmount ||
	    symbol_conf.default_guest_vmlinux_name ||
	    symbol_conf.default_guest_kallsyms ||
	    symbol_conf.default_guest_modules) {
		/*
		 * Enable guest sample processing.
		 */
		perf_guest = true;
	}

J
Jiri Olsa 已提交
3846 3847
	data.path  = input_name;
	data.force = symbol_conf.force;
3848

3849 3850 3851
	if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
		rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
		if (!rec_script_path)
3852
			return cmd_record(argc, argv);
3853 3854
	}

3855 3856 3857
	if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
		rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
		if (!rep_script_path) {
3858
			fprintf(stderr,
3859
				"Please specify a valid report script"
3860
				"(see 'perf script -l' for listing)\n");
3861 3862 3863 3864
			return -1;
		}
	}

3865 3866 3867 3868 3869 3870 3871
	if (reltime && deltatime) {
		fprintf(stderr,
			"reltime and deltatime - the two don't get along well. "
			"Please limit to --reltime or --deltatime.\n");
		return -1;
	}

3872
	if ((itrace_synth_opts.callchain || itrace_synth_opts.add_callchain) &&
3873 3874 3875
	    itrace_synth_opts.callchain_sz > scripting_max_stack)
		scripting_max_stack = itrace_synth_opts.callchain_sz;

3876
	/* make sure PERF_EXEC_PATH is set for scripts */
3877
	set_argv_exec_path(get_argv_exec_path());
3878

3879
	if (argc && !script_name && !rec_script_path && !rep_script_path) {
3880
		int live_pipe[2];
3881
		int rep_args;
3882 3883
		pid_t pid;

3884 3885 3886 3887
		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) {
3888 3889 3890 3891 3892 3893
			script_name = find_script(argv[0]);
			if (script_name) {
				argc -= 1;
				argv += 1;
				goto script_found;
			}
3894 3895
			usage_with_options_msg(script_usage, options,
				"Couldn't find script `%s'\n\n See perf"
3896
				" script -l for available scripts.\n", argv[0]);
3897 3898
		}

3899 3900 3901 3902 3903 3904 3905 3906
		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) {
3907 3908
				usage_with_options_msg(script_usage, options,
					"`%s' script requires options."
3909
					"\n\n See perf script -l for available "
3910 3911
					"scripts and options.\n", argv[0]);
			}
3912 3913 3914 3915
		}

		if (pipe(live_pipe) < 0) {
			perror("failed to create pipe");
3916
			return -1;
3917 3918 3919 3920 3921
		}

		pid = fork();
		if (pid < 0) {
			perror("failed to fork");
3922
			return -1;
3923 3924 3925
		}

		if (!pid) {
3926 3927
			j = 0;

3928 3929 3930
			dup2(live_pipe[1], 1);
			close(live_pipe[0]);

3931 3932 3933
			if (is_top_script(argv[0])) {
				system_wide = true;
			} else if (!system_wide) {
3934 3935 3936 3937
				if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
					err = -1;
					goto out;
				}
3938
			}
3939 3940

			__argv = malloc((argc + 6) * sizeof(const char *));
3941 3942 3943 3944 3945
			if (!__argv) {
				pr_err("malloc failed\n");
				err = -ENOMEM;
				goto out;
			}
3946

3947 3948 3949 3950 3951 3952 3953 3954 3955 3956
			__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;
3957 3958

			execvp("/bin/sh", (char **)__argv);
3959
			free(__argv);
3960 3961 3962 3963 3964 3965
			exit(-1);
		}

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

3966
		__argv = malloc((argc + 4) * sizeof(const char *));
3967 3968 3969 3970 3971 3972
		if (!__argv) {
			pr_err("malloc failed\n");
			err = -ENOMEM;
			goto out;
		}

3973 3974 3975 3976 3977 3978 3979 3980
		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;
3981 3982

		execvp("/bin/sh", (char **)__argv);
3983
		free(__argv);
3984 3985
		exit(-1);
	}
3986
script_found:
3987 3988 3989 3990
	if (rec_script_path)
		script_path = rec_script_path;
	if (rep_script_path)
		script_path = rep_script_path;
3991

3992 3993
	if (script_path) {
		j = 0;
3994

3995 3996
		if (!rec_script_path)
			system_wide = false;
3997 3998 3999 4000 4001 4002
		else if (!system_wide) {
			if (have_cmd(argc - 1, &argv[1]) != 0) {
				err = -1;
				goto out;
			}
		}
4003

4004
		__argv = malloc((argc + 2) * sizeof(const char *));
4005 4006 4007 4008 4009 4010
		if (!__argv) {
			pr_err("malloc failed\n");
			err = -ENOMEM;
			goto out;
		}

4011 4012 4013 4014
		__argv[j++] = "/bin/sh";
		__argv[j++] = script_path;
		if (system_wide)
			__argv[j++] = "-a";
4015
		for (i = 2; i < argc; i++)
4016 4017
			__argv[j++] = argv[i];
		__argv[j++] = NULL;
4018 4019

		execvp("/bin/sh", (char **)__argv);
4020
		free(__argv);
4021 4022
		exit(-1);
	}
T
Tom Zanussi 已提交
4023

4024
	if (dlfilter_file) {
4025
		dlfilter = dlfilter__new(dlfilter_file, dlargc, dlargv);
4026 4027 4028 4029
		if (!dlfilter)
			return -1;
	}

4030
	if (!script_name) {
4031
		setup_pager();
4032 4033
		use_browser = 0;
	}
F
Frederic Weisbecker 已提交
4034

4035
	session = perf_session__new(&data, &script.tool);
4036 4037
	if (IS_ERR(session))
		return PTR_ERR(session);
4038

4039
	if (header || header_only) {
4040
		script.tool.show_feat_hdr = SHOW_FEAT_HEADER;
4041 4042
		perf_session__fprintf_info(session, stdout, show_full_info);
		if (header_only)
4043
			goto out_delete;
4044
	}
4045 4046
	if (show_full_info)
		script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
4047

4048
	if (symbol__init(&session->header.env) < 0)
4049 4050
		goto out_delete;

4051
	uname(&uts);
4052
	if (data.is_pipe) { /* Assume pipe_mode indicates native_arch */
4053
		native_arch = true;
4054 4055 4056 4057 4058 4059 4060
	} 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;
	}
4061

4062
	script.session = session;
4063
	script__setup_sample_type(&script);
4064

4065 4066
	if ((output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT) ||
	    symbol_conf.graph_function)
4067 4068
		itrace_synth_opts.thread_stack = true;

4069 4070
	session->itrace_synth_opts = &itrace_synth_opts;

4071
	if (cpu_list) {
4072 4073 4074
		err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
		if (err < 0)
			goto out_delete;
4075
		itrace_synth_opts.cpu_bitmap = cpu_bitmap;
4076 4077
	}

4078
	if (!no_callchain)
4079 4080 4081 4082
		symbol_conf.use_callchain = true;
	else
		symbol_conf.use_callchain = false;

4083
	if (session->tevent.pevent &&
4084 4085 4086
	    tep_set_function_resolver(session->tevent.pevent,
				      machine__resolve_kernel_addr,
				      &session->machines.host) < 0) {
4087
		pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
4088 4089
		err = -1;
		goto out_delete;
4090 4091
	}

T
Tom Zanussi 已提交
4092 4093
	if (generate_script_lang) {
		struct stat perf_stat;
4094 4095
		int input;

4096
		if (output_set_by_user()) {
4097 4098
			fprintf(stderr,
				"custom fields not supported for generated scripts");
4099 4100
			err = -EINVAL;
			goto out_delete;
4101
		}
T
Tom Zanussi 已提交
4102

J
Jiri Olsa 已提交
4103
		input = open(data.path, O_RDONLY);	/* input_name */
T
Tom Zanussi 已提交
4104
		if (input < 0) {
4105
			err = -errno;
T
Tom Zanussi 已提交
4106
			perror("failed to open file");
4107
			goto out_delete;
T
Tom Zanussi 已提交
4108 4109 4110 4111 4112
		}

		err = fstat(input, &perf_stat);
		if (err < 0) {
			perror("failed to stat file");
4113
			goto out_delete;
T
Tom Zanussi 已提交
4114 4115 4116 4117
		}

		if (!perf_stat.st_size) {
			fprintf(stderr, "zero-sized file, nothing to do!\n");
4118
			goto out_delete;
T
Tom Zanussi 已提交
4119 4120 4121 4122 4123
		}

		scripting_ops = script_spec__lookup(generate_script_lang);
		if (!scripting_ops) {
			fprintf(stderr, "invalid language specifier");
4124 4125
			err = -ENOENT;
			goto out_delete;
T
Tom Zanussi 已提交
4126 4127
		}

J
Jiri Olsa 已提交
4128
		err = scripting_ops->generate_script(session->tevent.pevent,
4129
						     "perf-script");
4130
		goto out_delete;
T
Tom Zanussi 已提交
4131 4132
	}

4133 4134 4135 4136
	err = dlfilter__start(dlfilter, session);
	if (err)
		goto out_delete;

T
Tom Zanussi 已提交
4137
	if (script_name) {
4138
		err = scripting_ops->start_script(script_name, argc, argv, session);
T
Tom Zanussi 已提交
4139
		if (err)
4140
			goto out_delete;
4141
		pr_debug("perf script started with script %s\n\n", script_name);
4142
		script_started = true;
T
Tom Zanussi 已提交
4143 4144
	}

4145 4146 4147

	err = perf_session__check_output_opt(session);
	if (err < 0)
4148
		goto out_delete;
4149

4150
	if (script.time_str) {
4151
		err = perf_time__parse_for_ranges_reltime(script.time_str, session,
4152 4153
						  &script.ptime_range,
						  &script.range_size,
4154 4155
						  &script.range_num,
						  reltime);
4156
		if (err < 0)
4157
			goto out_delete;
4158 4159 4160 4161

		itrace_synth_opts__set_time_range(&itrace_synth_opts,
						  script.ptime_range,
						  script.range_num);
4162 4163
	}

4164 4165 4166
	err = evswitch__init(&script.evswitch, session->evlist, stderr);
	if (err)
		goto out_delete;
4167

M
Milian Wolff 已提交
4168 4169 4170
	if (zstd_init(&(session->zstd_data), 0) < 0)
		pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");

4171
	err = __cmd_script(&script);
T
Tom Zanussi 已提交
4172

4173 4174
	flush_scripting();

4175
out_delete:
4176 4177
	if (script.ptime_range) {
		itrace_synth_opts__clear_time_range(&itrace_synth_opts);
4178
		zfree(&script.ptime_range);
4179
	}
4180

4181
	zstd_fini(&(session->zstd_data));
4182
	evlist__free_stats(session->evlist);
4183
	perf_session__delete(session);
4184
	perf_script__exit(&script);
4185 4186 4187

	if (script_started)
		cleanup_scripting();
4188
	dlfilter__cleanup(dlfilter);
4189
	free_dlarg();
T
Tom Zanussi 已提交
4190 4191
out:
	return err;
F
Frederic Weisbecker 已提交
4192
}