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

#include "util/cache.h"
5
#include "util/counts.h"
A
Andrea Gelmini 已提交
6
#include "util/debug.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/evswitch.h"
21
#include "util/sort.h"
22
#include "util/data.h"
23
#include "util/auxtrace.h"
24 25 26
#include "util/cpumap.h"
#include "util/thread_map.h"
#include "util/stat.h"
27
#include "util/color.h"
28
#include "util/string2.h"
29
#include "util/thread-stack.h"
30
#include "util/time-utils.h"
31
#include "util/path.h"
32
#include "print_binary.h"
33
#include "archinsn.h"
34
#include <linux/bitmap.h>
35
#include <linux/kernel.h>
36
#include <linux/stringify.h>
37
#include <linux/time64.h>
38
#include <linux/zalloc.h>
39
#include <sys/utsname.h>
40
#include "asm/bug.h"
J
Jiri Olsa 已提交
41
#include "util/mem-events.h"
42
#include "util/dump-insn.h"
43
#include <dirent.h>
44
#include <errno.h>
45
#include <inttypes.h>
46
#include <signal.h>
47
#include <sys/param.h>
48 49
#include <sys/types.h>
#include <sys/stat.h>
50
#include <fcntl.h>
51
#include <unistd.h>
52
#include <subcmd/pager.h>
53
#include <perf/evlist.h>
54
#include "util/record.h"
55
#include "util/util.h"
F
Frederic Weisbecker 已提交
56

57
#include <linux/ctype.h>
58

T
Tom Zanussi 已提交
59 60
static char const		*script_name;
static char const		*generate_script_lang;
A
Andi Kleen 已提交
61 62
static bool			reltime;
static u64			initial_time;
63
static bool			debug_mode;
64
static u64			last_timestamp;
65
static u64			nr_unordered;
66
static bool			no_callchain;
67
static bool			latency_format;
68
static bool			system_wide;
69
static bool			print_flags;
70 71
static const char		*cpu_list;
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
72
static struct perf_stat_config	stat_config;
73
static int			max_blocks;
74
static bool			native_arch;
T
Tom Zanussi 已提交
75

76
unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
77

78 79 80 81 82 83 84 85
enum perf_output_field {
	PERF_OUTPUT_COMM            = 1U << 0,
	PERF_OUTPUT_TID             = 1U << 1,
	PERF_OUTPUT_PID             = 1U << 2,
	PERF_OUTPUT_TIME            = 1U << 3,
	PERF_OUTPUT_CPU             = 1U << 4,
	PERF_OUTPUT_EVNAME          = 1U << 5,
	PERF_OUTPUT_TRACE           = 1U << 6,
86 87
	PERF_OUTPUT_IP              = 1U << 7,
	PERF_OUTPUT_SYM             = 1U << 8,
88
	PERF_OUTPUT_DSO             = 1U << 9,
89
	PERF_OUTPUT_ADDR            = 1U << 10,
90
	PERF_OUTPUT_SYMOFFSET       = 1U << 11,
91
	PERF_OUTPUT_SRCLINE         = 1U << 12,
J
Jiri Olsa 已提交
92
	PERF_OUTPUT_PERIOD          = 1U << 13,
93
	PERF_OUTPUT_IREGS	    = 1U << 14,
94 95
	PERF_OUTPUT_BRSTACK	    = 1U << 15,
	PERF_OUTPUT_BRSTACKSYM	    = 1U << 16,
96 97
	PERF_OUTPUT_DATA_SRC	    = 1U << 17,
	PERF_OUTPUT_WEIGHT	    = 1U << 18,
98
	PERF_OUTPUT_BPF_OUTPUT	    = 1U << 19,
99
	PERF_OUTPUT_CALLINDENT	    = 1U << 20,
A
Andi Kleen 已提交
100 101
	PERF_OUTPUT_INSN	    = 1U << 21,
	PERF_OUTPUT_INSNLEN	    = 1U << 22,
102
	PERF_OUTPUT_BRSTACKINSN	    = 1U << 23,
103
	PERF_OUTPUT_BRSTACKOFF	    = 1U << 24,
104
	PERF_OUTPUT_SYNTH           = 1U << 25,
105
	PERF_OUTPUT_PHYS_ADDR       = 1U << 26,
A
Andi Kleen 已提交
106
	PERF_OUTPUT_UREGS	    = 1U << 27,
107
	PERF_OUTPUT_METRIC	    = 1U << 28,
108
	PERF_OUTPUT_MISC            = 1U << 29,
A
Andi Kleen 已提交
109
	PERF_OUTPUT_SRCCODE	    = 1U << 30,
110
	PERF_OUTPUT_IPC             = 1U << 31,
111 112 113 114 115 116 117 118 119 120 121 122 123
};

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},
124
	{.str = "ip",    .field = PERF_OUTPUT_IP},
125
	{.str = "sym",   .field = PERF_OUTPUT_SYM},
126
	{.str = "dso",   .field = PERF_OUTPUT_DSO},
127
	{.str = "addr",  .field = PERF_OUTPUT_ADDR},
128
	{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
129
	{.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
J
Jiri Olsa 已提交
130
	{.str = "period", .field = PERF_OUTPUT_PERIOD},
131
	{.str = "iregs", .field = PERF_OUTPUT_IREGS},
A
Andi Kleen 已提交
132
	{.str = "uregs", .field = PERF_OUTPUT_UREGS},
133 134
	{.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
	{.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
135 136
	{.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},
	{.str = "weight",   .field = PERF_OUTPUT_WEIGHT},
137
	{.str = "bpf-output",   .field = PERF_OUTPUT_BPF_OUTPUT},
138
	{.str = "callindent", .field = PERF_OUTPUT_CALLINDENT},
A
Andi Kleen 已提交
139 140
	{.str = "insn", .field = PERF_OUTPUT_INSN},
	{.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},
141
	{.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
142
	{.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
143
	{.str = "synth", .field = PERF_OUTPUT_SYNTH},
144
	{.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
145
	{.str = "metric", .field = PERF_OUTPUT_METRIC},
146
	{.str = "misc", .field = PERF_OUTPUT_MISC},
A
Andi Kleen 已提交
147
	{.str = "srccode", .field = PERF_OUTPUT_SRCCODE},
148
	{.str = "ipc", .field = PERF_OUTPUT_IPC},
149 150
};

151 152 153 154 155
enum {
	OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,
	OUTPUT_TYPE_MAX
};

156
/* default set to maintain compatibility with current format */
157 158
static struct {
	bool user_set;
159
	bool wildcard_set;
160
	unsigned int print_ip_opts;
161 162
	u64 fields;
	u64 invalid_fields;
163
	u64 user_set_fields;
164
} output[OUTPUT_TYPE_MAX] = {
165 166 167 168 169 170

	[PERF_TYPE_HARDWARE] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
171
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
172 173
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
174

175
		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
176 177 178 179 180 181 182
	},

	[PERF_TYPE_SOFTWARE] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
183
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
184 185 186
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
			      PERF_OUTPUT_BPF_OUTPUT,
187 188 189 190 191 192 193 194 195

		.invalid_fields = PERF_OUTPUT_TRACE,
	},

	[PERF_TYPE_TRACEPOINT] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
				  PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
196
				  PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE
197
	},
198

199 200 201 202 203 204 205 206 207 208 209 210
	[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,
	},

211 212 213 214 215
	[PERF_TYPE_RAW] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
216
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
217 218 219 220
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
			      PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC |
			      PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR,
221

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

	[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 |
231 232
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
233

234
		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
235
	},
236 237 238 239 240 241 242

	[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 |
243 244
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_SYNTH,
245 246 247

		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
	},
248
};
249

250
struct evsel_script {
251 252 253
       char *filename;
       FILE *fp;
       u64  samples;
254 255 256
       /* For metric output */
       u64  val;
       int  gnum;
257 258
};

259
static inline struct evsel_script *evsel_script(struct evsel *evsel)
260
{
261
	return (struct evsel_script *)evsel->priv;
262 263
}

264
static struct evsel_script *perf_evsel_script__new(struct evsel *evsel,
265
							struct perf_data *data)
266
{
267
	struct evsel_script *es = zalloc(sizeof(*es));
268 269

	if (es != NULL) {
J
Jiri Olsa 已提交
270
		if (asprintf(&es->filename, "%s.%s.dump", data->file.path, perf_evsel__name(evsel)) < 0)
271 272 273 274 275 276 277 278 279 280 281 282 283 284
			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;
}

285
static void perf_evsel_script__delete(struct evsel_script *es)
286 287 288 289 290 291 292
{
	zfree(&es->filename);
	fclose(es->fp);
	es->fp = NULL;
	free(es);
}

293
static int perf_evsel_script__fprintf(struct evsel_script *es, FILE *fp)
294 295 296 297 298 299 300 301
{
	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);
}

302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
static inline int output_type(unsigned int type)
{
	switch (type) {
	case PERF_TYPE_SYNTH:
		return OUTPUT_TYPE_SYNTH;
	default:
		return type;
	}
}

static inline unsigned int attr_type(unsigned int type)
{
	switch (type) {
	case OUTPUT_TYPE_SYNTH:
		return PERF_TYPE_SYNTH;
	default:
		return type;
	}
}

322 323 324
static bool output_set_by_user(void)
{
	int j;
325
	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
326 327 328 329 330
		if (output[j].user_set)
			return true;
	}
	return false;
}
331

332 333 334 335 336 337 338 339 340 341 342 343 344 345
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;
}

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

348
static int perf_evsel__do_check_stype(struct evsel *evsel,
349 350 351
				      u64 sample_type, const char *sample_msg,
				      enum perf_output_field field,
				      bool allow_user_set)
352
{
353
	struct perf_event_attr *attr = &evsel->core.attr;
354
	int type = output_type(attr->type);
355 356 357 358 359
	const char *evname;

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

360
	if (output[type].user_set_fields & field) {
361 362
		if (allow_user_set)
			return 0;
363
		evname = perf_evsel__name(evsel);
364 365 366 367 368 369 370 371
		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;
372
	evname = perf_evsel__name(evsel);
373 374 375 376 377 378 379
	pr_debug("Samples for '%s' event do not have %s attribute set. "
		 "Skipping '%s' field.\n",
		 evname, sample_msg, output_field2str(field));

	return 0;
}

380
static int perf_evsel__check_stype(struct evsel *evsel,
381 382 383 384 385 386 387
				   u64 sample_type, const char *sample_msg,
				   enum perf_output_field field)
{
	return perf_evsel__do_check_stype(evsel, sample_type, sample_msg, field,
					  false);
}

388
static int perf_evsel__check_attr(struct evsel *evsel,
389 390
				  struct perf_session *session)
{
391
	struct perf_event_attr *attr = &evsel->core.attr;
392 393
	bool allow_user_set;

394 395 396
	if (perf_header__has_feat(&session->header, HEADER_STAT))
		return 0;

397 398
	allow_user_set = perf_header__has_feat(&session->header,
					       HEADER_AUXTRACE);
399

400 401 402 403
	if (PRINT_FIELD(TRACE) &&
		!perf_session__has_traces(session, "record -R"))
		return -EINVAL;

404
	if (PRINT_FIELD(IP)) {
405 406
		if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP",
					    PERF_OUTPUT_IP))
407 408
			return -EINVAL;
	}
409 410

	if (PRINT_FIELD(ADDR) &&
411 412
		perf_evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR",
					   PERF_OUTPUT_ADDR, allow_user_set))
413 414
		return -EINVAL;

415 416 417 418 419 420 421 422 423 424
	if (PRINT_FIELD(DATA_SRC) &&
		perf_evsel__check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC",
					PERF_OUTPUT_DATA_SRC))
		return -EINVAL;

	if (PRINT_FIELD(WEIGHT) &&
		perf_evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT, "WEIGHT",
					PERF_OUTPUT_WEIGHT))
		return -EINVAL;

425
	if (PRINT_FIELD(SYM) &&
426
		!(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
427
		pr_err("Display of symbols requested but neither sample IP nor "
428
			   "sample address\navailable. Hence, no addresses to convert "
429
		       "to symbols.\n");
430 431
		return -EINVAL;
	}
432 433 434 435 436
	if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
		pr_err("Display of offsets requested but symbol is not"
		       "selected.\n");
		return -EINVAL;
	}
437
	if (PRINT_FIELD(DSO) &&
438
		!(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
439
		pr_err("Display of DSO requested but no address to convert.\n");
440 441
		return -EINVAL;
	}
A
Andi Kleen 已提交
442
	if ((PRINT_FIELD(SRCLINE) || PRINT_FIELD(SRCCODE)) && !PRINT_FIELD(IP)) {
443 444 445 446
		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;
	}
447 448 449 450 451 452 453
	if (PRINT_FIELD(BRSTACKINSN) &&
	    !(perf_evlist__combined_branch_type(session->evlist) &
	      PERF_SAMPLE_BRANCH_ANY)) {
		pr_err("Display of branch stack assembler requested, but non all-branch filter set\n"
		       "Hint: run 'perf record -b ...'\n");
		return -EINVAL;
	}
454
	if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
455 456
		perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID",
					PERF_OUTPUT_TID|PERF_OUTPUT_PID))
457 458 459
		return -EINVAL;

	if (PRINT_FIELD(TIME) &&
460 461
		perf_evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME",
					PERF_OUTPUT_TIME))
462 463 464
		return -EINVAL;

	if (PRINT_FIELD(CPU) &&
465 466
		perf_evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU",
					   PERF_OUTPUT_CPU, allow_user_set))
467
		return -EINVAL;
468

469 470 471 472 473
	if (PRINT_FIELD(IREGS) &&
		perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS",
					PERF_OUTPUT_IREGS))
		return -EINVAL;

A
Andi Kleen 已提交
474 475 476 477 478
	if (PRINT_FIELD(UREGS) &&
		perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS",
					PERF_OUTPUT_UREGS))
		return -EINVAL;

479 480 481 482 483
	if (PRINT_FIELD(PHYS_ADDR) &&
		perf_evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR",
					PERF_OUTPUT_PHYS_ADDR))
		return -EINVAL;

484 485 486
	return 0;
}

487 488
static void set_print_ip_opts(struct perf_event_attr *attr)
{
489
	unsigned int type = output_type(attr->type);
490 491 492

	output[type].print_ip_opts = 0;
	if (PRINT_FIELD(IP))
493
		output[type].print_ip_opts |= EVSEL__PRINT_IP;
494 495

	if (PRINT_FIELD(SYM))
496
		output[type].print_ip_opts |= EVSEL__PRINT_SYM;
497 498

	if (PRINT_FIELD(DSO))
499
		output[type].print_ip_opts |= EVSEL__PRINT_DSO;
500 501

	if (PRINT_FIELD(SYMOFFSET))
502
		output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET;
503 504

	if (PRINT_FIELD(SRCLINE))
505
		output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
506 507
}

508 509 510 511 512 513
/*
 * verify all user requested events exist and the samples
 * have the expected data
 */
static int perf_session__check_output_opt(struct perf_session *session)
{
514
	unsigned int j;
515
	struct evsel *evsel;
516

517 518
	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
		evsel = perf_session__find_first_evtype(session, attr_type(j));
519 520 521 522 523

		/*
		 * even if fields is set to 0 (ie., show nothing) event must
		 * exist if user explicitly includes it on the command line
		 */
524 525
		if (!evsel && output[j].user_set && !output[j].wildcard_set &&
		    j != OUTPUT_TYPE_SYNTH) {
526
			pr_err("%s events do not exist. "
527
			       "Remove corresponding -F option to proceed.\n",
528 529 530 531 532 533 534
			       event_type(j));
			return -1;
		}

		if (evsel && output[j].fields &&
			perf_evsel__check_attr(evsel, session))
			return -1;
535 536 537 538

		if (evsel == NULL)
			continue;

539
		set_print_ip_opts(&evsel->core.attr);
540 541
	}

542 543
	if (!no_callchain) {
		bool use_callchain = false;
544
		bool not_pipe = false;
545

546
		evlist__for_each_entry(session->evlist, evsel) {
547
			not_pipe = true;
548
			if (evsel__has_callchain(evsel)) {
549 550 551 552
				use_callchain = true;
				break;
			}
		}
553
		if (not_pipe && !use_callchain)
554 555 556
			symbol_conf.use_callchain = false;
	}

557 558 559 560 561 562 563 564
	/*
	 * 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;

565
		evlist__for_each_entry(session->evlist, evsel) {
566
			if (evsel->core.attr.type != j)
567 568
				continue;

569
			if (evsel__has_callchain(evsel)) {
570 571
				output[j].fields |= PERF_OUTPUT_IP;
				output[j].fields |= PERF_OUTPUT_SYM;
572
				output[j].fields |= PERF_OUTPUT_SYMOFFSET;
573
				output[j].fields |= PERF_OUTPUT_DSO;
574
				set_print_ip_opts(&evsel->core.attr);
575 576
				goto out;
			}
577 578 579 580
		}
	}

out:
581 582
	return 0;
}
583

584 585 586
static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask,
				     FILE *fp
)
A
Andi Kleen 已提交
587 588
{
	unsigned i = 0, r;
589
	int printed = 0;
A
Andi Kleen 已提交
590 591

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

594
	printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi);
A
Andi Kleen 已提交
595 596 597

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

601 602
	fprintf(fp, "\n");

603
	return printed;
A
Andi Kleen 已提交
604 605
}

606 607 608 609 610 611 612 613 614 615 616 617 618 619
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);
}

620 621
static int perf_sample__fprintf_start(struct perf_sample *sample,
				      struct thread *thread,
622
				      struct evsel *evsel,
623
				      u32 type, FILE *fp)
624
{
625
	struct perf_event_attr *attr = &evsel->core.attr;
626
	unsigned long secs;
627
	unsigned long long nsecs;
628
	int printed = 0;
629 630 631

	if (PRINT_FIELD(COMM)) {
		if (latency_format)
632
			printed += fprintf(fp, "%8.8s ", thread__comm_str(thread));
633
		else if (PRINT_FIELD(IP) && evsel__has_callchain(evsel) && symbol_conf.use_callchain)
634
			printed += fprintf(fp, "%s ", thread__comm_str(thread));
635
		else
636
			printed += fprintf(fp, "%16s ", thread__comm_str(thread));
637
	}
638

639
	if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
640
		printed += fprintf(fp, "%5d/%-5d ", sample->pid, sample->tid);
641
	else if (PRINT_FIELD(PID))
642
		printed += fprintf(fp, "%5d ", sample->pid);
643
	else if (PRINT_FIELD(TID))
644
		printed += fprintf(fp, "%5d ", sample->tid);
645 646 647

	if (PRINT_FIELD(CPU)) {
		if (latency_format)
648
			printed += fprintf(fp, "%3d ", sample->cpu);
649
		else
650
			printed += fprintf(fp, "[%03d] ", sample->cpu);
651
	}
652

653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
	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:
682
			if (has(SWITCH_OUT)) {
683
				ret += fprintf(fp, "S");
684 685 686
				if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT)
					ret += fprintf(fp, "p");
			}
687 688 689 690 691 692 693 694 695 696
		default:
			break;
		}

		#undef has

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

697
	if (PRINT_FIELD(TIME)) {
A
Andi Kleen 已提交
698 699 700 701 702 703 704
		u64 t = sample->time;
		if (reltime) {
			if (!initial_time)
				initial_time = sample->time;
			t = sample->time - initial_time;
		}
		nsecs = t;
705 706
		secs = nsecs / NSEC_PER_SEC;
		nsecs -= secs * NSEC_PER_SEC;
707

708
		if (symbol_conf.nanosecs)
709
			printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs);
710 711
		else {
			char sample_time[32];
A
Andi Kleen 已提交
712
			timestamp__scnprintf_usec(t, sample_time, sizeof(sample_time));
713
			printed += fprintf(fp, "%12s: ", sample_time);
714
		}
715
	}
716 717

	return printed;
718 719
}

720 721 722 723 724 725 726 727 728
static inline char
mispred_str(struct branch_entry *br)
{
	if (!(br->flags.mispred  || br->flags.predicted))
		return '-';

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

729 730 731
static int perf_sample__fprintf_brstack(struct perf_sample *sample,
					struct thread *thread,
					struct perf_event_attr *attr, FILE *fp)
732 733
{
	struct branch_stack *br = sample->branch_stack;
734 735
	struct addr_location alf, alt;
	u64 i, from, to;
736
	int printed = 0;
737 738

	if (!(br && br->nr))
739
		return 0;
740 741

	for (i = 0; i < br->nr; i++) {
742 743 744 745 746 747
		from = br->entries[i].from;
		to   = br->entries[i].to;

		if (PRINT_FIELD(DSO)) {
			memset(&alf, 0, sizeof(alf));
			memset(&alt, 0, sizeof(alt));
748 749
			thread__find_map_fb(thread, sample->cpumode, from, &alf);
			thread__find_map_fb(thread, sample->cpumode, to, &alt);
750 751
		}

752
		printed += fprintf(fp, " 0x%"PRIx64, from);
753
		if (PRINT_FIELD(DSO)) {
754 755 756
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alf.map, fp);
			printed += fprintf(fp, ")");
757 758
		}

759
		printed += fprintf(fp, "/0x%"PRIx64, to);
760
		if (PRINT_FIELD(DSO)) {
761 762 763
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alt.map, fp);
			printed += fprintf(fp, ")");
764 765
		}

766
		printed += fprintf(fp, "/%c/%c/%c/%d ",
767 768 769 770 771
			mispred_str( br->entries + i),
			br->entries[i].flags.in_tx? 'X' : '-',
			br->entries[i].flags.abort? 'A' : '-',
			br->entries[i].flags.cycles);
	}
772 773

	return printed;
774 775
}

776 777 778
static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
					   struct thread *thread,
					   struct perf_event_attr *attr, FILE *fp)
779 780 781 782
{
	struct branch_stack *br = sample->branch_stack;
	struct addr_location alf, alt;
	u64 i, from, to;
783
	int printed = 0;
784 785

	if (!(br && br->nr))
786
		return 0;
787 788 789 790 791 792 793 794

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

		memset(&alf, 0, sizeof(alf));
		memset(&alt, 0, sizeof(alt));
		from = br->entries[i].from;
		to   = br->entries[i].to;

795 796
		thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
		thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
797

798
		printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
799
		if (PRINT_FIELD(DSO)) {
800 801 802
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alf.map, fp);
			printed += fprintf(fp, ")");
803
		}
804 805
		printed += fprintf(fp, "%c", '/');
		printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp);
806
		if (PRINT_FIELD(DSO)) {
807 808 809
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alt.map, fp);
			printed += fprintf(fp, ")");
810
		}
811
		printed += fprintf(fp, "/%c/%c/%c/%d ",
812 813 814 815 816
			mispred_str( br->entries + i),
			br->entries[i].flags.in_tx? 'X' : '-',
			br->entries[i].flags.abort? 'A' : '-',
			br->entries[i].flags.cycles);
	}
817 818

	return printed;
819 820
}

821 822 823
static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
					   struct thread *thread,
					   struct perf_event_attr *attr, FILE *fp)
824 825 826 827
{
	struct branch_stack *br = sample->branch_stack;
	struct addr_location alf, alt;
	u64 i, from, to;
828
	int printed = 0;
829 830

	if (!(br && br->nr))
831
		return 0;
832 833 834 835 836 837 838 839

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

		memset(&alf, 0, sizeof(alf));
		memset(&alt, 0, sizeof(alt));
		from = br->entries[i].from;
		to   = br->entries[i].to;

840
		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
841
		    !alf.map->dso->adjust_symbols)
842 843
			from = map__map_ip(alf.map, from);

844
		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
845
		    !alt.map->dso->adjust_symbols)
846 847
			to = map__map_ip(alt.map, to);

848
		printed += fprintf(fp, " 0x%"PRIx64, from);
849
		if (PRINT_FIELD(DSO)) {
850 851 852
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alf.map, fp);
			printed += fprintf(fp, ")");
853
		}
854
		printed += fprintf(fp, "/0x%"PRIx64, to);
855
		if (PRINT_FIELD(DSO)) {
856 857 858
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alt.map, fp);
			printed += fprintf(fp, ")");
859
		}
860
		printed += fprintf(fp, "/%c/%c/%c/%d ",
861 862 863 864 865
			mispred_str(br->entries + i),
			br->entries[i].flags.in_tx ? 'X' : '-',
			br->entries[i].flags.abort ? 'A' : '-',
			br->entries[i].flags.cycles);
	}
866 867

	return printed;
868
}
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894
#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)) {
895
		pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end);
896 897 898 899 900 901
		return -ENXIO;
	}

	memset(&al, 0, sizeof(al));
	if (end - start > MAXBB - MAXINSN) {
		if (last)
902
			pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end);
903
		else
904
			pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start);
905 906 907
		return 0;
	}

908
	if (!thread__find_map(thread, *cpumode, start, &al) || !al.map->dso) {
909
		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
910 911 912
		return 0;
	}
	if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) {
913
		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
914 915 916 917 918 919 920 921 922 923 924 925
		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)
926
		pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
927 928 929 930
			start, end);
	return len;
}

A
Andi Kleen 已提交
931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946
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;
}

947 948
static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
			    struct perf_insn *x, u8 *inbuf, int len,
949
			    int insn, FILE *fp, int *total_cycles)
950
{
951 952 953 954 955 956
	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" : "");
957
	if (en->flags.cycles) {
958 959
		*total_cycles += en->flags.cycles;
		printed += fprintf(fp, " %d cycles [%d]", en->flags.cycles, *total_cycles);
960
		if (insn)
961
			printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
962
	}
963
	return printed + fprintf(fp, "\n");
964 965
}

966 967 968
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)
969 970
{
	struct addr_location al;
971
	int off, printed = 0;
972 973 974

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

975 976
	thread__find_map(thread, cpumode, addr, &al);

977
	if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
978
		return 0;
979 980 981 982 983 984 985

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

	if (!al.sym)
986
		return 0;
987 988 989 990 991

	if (al.addr < al.sym->end)
		off = al.addr - al.sym->start;
	else
		off = al.addr - al.map->start - al.sym->start;
992
	printed += fprintf(fp, "\t%s", al.sym->name);
993
	if (off)
994 995
		printed += fprintf(fp, "%+d", off);
	printed += fprintf(fp, ":");
996
	if (PRINT_FIELD(SRCLINE))
997 998
		printed += map__fprintf_srcline(al.map, al.addr, "\t", fp);
	printed += fprintf(fp, "\n");
999
	*lastsym = al.sym;
1000 1001

	return printed;
1002 1003
}

1004 1005 1006 1007
static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
					    struct thread *thread,
					    struct perf_event_attr *attr,
					    struct machine *machine, FILE *fp)
1008 1009 1010
{
	struct branch_stack *br = sample->branch_stack;
	u64 start, end;
1011
	int i, insn, len, nr, ilen, printed = 0;
1012 1013 1014 1015
	struct perf_insn x;
	u8 buffer[MAXBB];
	unsigned off;
	struct symbol *lastsym = NULL;
1016
	int total_cycles = 0;
1017 1018

	if (!(br && br->nr))
1019
		return 0;
1020 1021 1022 1023 1024 1025 1026
	nr = br->nr;
	if (max_blocks && nr > max_blocks + 1)
		nr = max_blocks + 1;

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

1027
	printed += fprintf(fp, "%c", '\n');
1028 1029 1030 1031 1032 1033

	/* Handle first from jump, of which we don't know the entry. */
	len = grab_bb(buffer, br->entries[nr-1].from,
			br->entries[nr-1].from,
			machine, thread, &x.is64bit, &x.cpumode, false);
	if (len > 0) {
1034 1035 1036
		printed += ip__fprintf_sym(br->entries[nr - 1].from, thread,
					   x.cpumode, x.cpu, &lastsym, attr, fp);
		printed += ip__fprintf_jump(br->entries[nr - 1].from, &br->entries[nr - 1],
1037
					    &x, buffer, len, 0, fp, &total_cycles);
A
Andi Kleen 已提交
1038 1039
		if (PRINT_FIELD(SRCCODE))
			printed += print_srccode(thread, x.cpumode, br->entries[nr - 1].from);
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064
	}

	/* Print all blocks */
	for (i = nr - 2; i >= 0; i--) {
		if (br->entries[i].from || br->entries[i].to)
			pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i,
				 br->entries[i].from,
				 br->entries[i].to);
		start = br->entries[i + 1].to;
		end   = br->entries[i].from;

		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) {
			end = br->entries[--i].from;
			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;
		for (off = 0;; off += ilen) {
			uint64_t ip = start + off;

1065
			printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
1066
			if (ip == end) {
1067
				printed += ip__fprintf_jump(ip, &br->entries[i], &x, buffer + off, len - off, ++insn, fp,
1068
							    &total_cycles);
A
Andi Kleen 已提交
1069 1070
				if (PRINT_FIELD(SRCCODE))
					printed += print_srccode(thread, x.cpumode, ip);
1071 1072
				break;
			} else {
1073 1074
				printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip,
						   dump_insn(&x, ip, buffer + off, len - off, &ilen));
1075 1076
				if (ilen == 0)
					break;
A
Andi Kleen 已提交
1077 1078
				if (PRINT_FIELD(SRCCODE))
					print_srccode(thread, x.cpumode, ip);
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088
				insn++;
			}
		}
	}

	/*
	 * Hit the branch? In this case we are already done, and the target
	 * has not been executed yet.
	 */
	if (br->entries[0].from == sample->ip)
1089
		goto out;
1090
	if (br->entries[0].flags.abort)
1091
		goto out;
1092 1093 1094

	/*
	 * Print final block upto sample
1095 1096 1097 1098 1099
	 *
	 * 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.
1100 1101 1102
	 */
	start = br->entries[0].to;
	end = sample->ip;
1103 1104 1105 1106
	if (end < start) {
		/* Missing jump. Scan 128 bytes for the next branch */
		end = start + 128;
	}
1107
	len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
1108
	printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
1109 1110 1111 1112 1113
	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)
1114 1115
			goto out;
		printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip,
1116
			dump_insn(&x, sample->ip, buffer, len, NULL));
A
Andi Kleen 已提交
1117 1118
		if (PRINT_FIELD(SRCCODE))
			print_srccode(thread, x.cpumode, sample->ip);
1119
		goto out;
1120 1121
	}
	for (off = 0; off <= end - start; off += ilen) {
1122 1123
		printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", start + off,
				   dump_insn(&x, start + off, buffer + off, len - off, &ilen));
1124 1125
		if (ilen == 0)
			break;
1126 1127 1128 1129 1130 1131 1132
		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 已提交
1133 1134
		if (PRINT_FIELD(SRCCODE))
			print_srccode(thread, x.cpumode, start + off);
1135
	}
1136 1137
out:
	return printed;
1138
}
1139

1140 1141 1142
static int perf_sample__fprintf_addr(struct perf_sample *sample,
				     struct thread *thread,
				     struct perf_event_attr *attr, FILE *fp)
1143 1144
{
	struct addr_location al;
1145
	int printed = fprintf(fp, "%16" PRIx64, sample->addr);
1146 1147

	if (!sample_addr_correlates_sym(attr))
1148
		goto out;
1149

1150
	thread__resolve(thread, &al, sample);
1151 1152

	if (PRINT_FIELD(SYM)) {
1153
		printed += fprintf(fp, " ");
1154
		if (PRINT_FIELD(SYMOFFSET))
1155
			printed += symbol__fprintf_symname_offs(al.sym, &al, fp);
1156
		else
1157
			printed += symbol__fprintf_symname(al.sym, fp);
1158 1159 1160
	}

	if (PRINT_FIELD(DSO)) {
1161 1162 1163
		printed += fprintf(fp, " (");
		printed += map__fprintf_dsoname(al.map, fp);
		printed += fprintf(fp, ")");
1164
	}
1165 1166
out:
	return printed;
1167 1168
}

1169
static const char *resolve_branch_sym(struct perf_sample *sample,
1170
				      struct evsel *evsel,
1171 1172 1173 1174 1175
				      struct thread *thread,
				      struct addr_location *al,
				      u64 *ip)
{
	struct addr_location addr_al;
1176
	struct perf_event_attr *attr = &evsel->core.attr;
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197
	const char *name = NULL;

	if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) {
		if (sample_addr_correlates_sym(attr)) {
			thread__resolve(thread, &addr_al, sample);
			if (addr_al.sym)
				name = addr_al.sym->name;
			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;
}

1198
static int perf_sample__fprintf_callindent(struct perf_sample *sample,
1199
					   struct evsel *evsel,
1200 1201
					   struct thread *thread,
					   struct addr_location *al, FILE *fp)
1202
{
1203
	struct perf_event_attr *attr = &evsel->core.attr;
1204
	size_t depth = thread_stack__depth(thread, sample->cpu);
1205 1206 1207
	const char *name = NULL;
	static int spacing;
	int len = 0;
1208
	int dlen = 0;
1209 1210 1211 1212 1213 1214 1215 1216 1217
	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;

1218
	name = resolve_branch_sym(sample, evsel, thread, al, &ip);
1219

1220 1221 1222 1223 1224 1225
	if (PRINT_FIELD(DSO) && !(PRINT_FIELD(IP) || PRINT_FIELD(ADDR))) {
		dlen += fprintf(fp, "(");
		dlen += map__fprintf_dsoname(al->map, fp);
		dlen += fprintf(fp, ")\t");
	}

1226
	if (name)
1227
		len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);
1228
	else if (ip)
1229
		len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip);
1230 1231

	if (len < 0)
1232
		return len;
1233 1234 1235 1236 1237 1238 1239 1240 1241

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

1244
	return len + dlen;
1245 1246
}

1247 1248 1249 1250 1251 1252
__weak void arch_fetch_insn(struct perf_sample *sample __maybe_unused,
			    struct thread *thread __maybe_unused,
			    struct machine *machine __maybe_unused)
{
}

1253 1254 1255 1256
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 已提交
1257
{
1258 1259
	int printed = 0;

1260 1261 1262
	if (sample->insn_len == 0 && native_arch)
		arch_fetch_insn(sample, thread, machine);

A
Andi Kleen 已提交
1263
	if (PRINT_FIELD(INSNLEN))
1264
		printed += fprintf(fp, " ilen: %d", sample->insn_len);
1265
	if (PRINT_FIELD(INSN) && sample->insn_len) {
A
Andi Kleen 已提交
1266 1267
		int i;

1268
		printed += fprintf(fp, " insn:");
A
Andi Kleen 已提交
1269
		for (i = 0; i < sample->insn_len; i++)
1270
			printed += fprintf(fp, " %02x", (unsigned char)sample->insn[i]);
A
Andi Kleen 已提交
1271
	}
1272
	if (PRINT_FIELD(BRSTACKINSN))
1273 1274 1275
		printed += perf_sample__fprintf_brstackinsn(sample, thread, attr, machine, fp);

	return printed;
A
Andi Kleen 已提交
1276 1277
}

1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291
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);
}

1292
static int perf_sample__fprintf_bts(struct perf_sample *sample,
1293
				    struct evsel *evsel,
1294 1295 1296
				    struct thread *thread,
				    struct addr_location *al,
				    struct machine *machine, FILE *fp)
1297
{
1298
	struct perf_event_attr *attr = &evsel->core.attr;
1299
	unsigned int type = output_type(attr->type);
1300
	bool print_srcline_last = false;
1301
	int printed = 0;
1302

1303
	if (PRINT_FIELD(CALLINDENT))
1304
		printed += perf_sample__fprintf_callindent(sample, evsel, thread, al, fp);
1305

1306 1307
	/* print branch_from information */
	if (PRINT_FIELD(IP)) {
1308
		unsigned int print_opts = output[type].print_ip_opts;
1309
		struct callchain_cursor *cursor = NULL;
1310

1311
		if (symbol_conf.use_callchain && sample->callchain &&
1312
		    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
1313
					      sample, NULL, NULL, scripting_max_stack) == 0)
1314
			cursor = &callchain_cursor;
1315 1316

		if (cursor == NULL) {
1317
			printed += fprintf(fp, " ");
1318
			if (print_opts & EVSEL__PRINT_SRCLINE) {
1319
				print_srcline_last = true;
1320
				print_opts &= ~EVSEL__PRINT_SRCLINE;
1321
			}
1322
		} else
1323
			printed += fprintf(fp, "\n");
1324

1325
		printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor, fp);
1326 1327 1328
	}

	/* print branch_to information */
1329
	if (PRINT_FIELD(ADDR) ||
1330
	    ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
1331
	     !output[type].user_set)) {
1332 1333
		printed += fprintf(fp, " => ");
		printed += perf_sample__fprintf_addr(sample, thread, attr, fp);
1334
	}
1335

1336 1337
	printed += perf_sample__fprintf_ipc(sample, attr, fp);

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

1341
	printed += perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
A
Andi Kleen 已提交
1342 1343 1344 1345 1346 1347 1348 1349 1350 1351
	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;
1352 1353
}

1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373
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"},
	{0, NULL}
};

1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385
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;
}

1386
static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
1387 1388 1389
{
	const char *chars = PERF_IP_FLAG_CHARS;
	const int n = strlen(PERF_IP_FLAG_CHARS);
1390 1391
	bool in_tx = flags & PERF_IP_FLAG_IN_TX;
	const char *name = NULL;
1392 1393 1394
	char str[33];
	int i, pos = 0;

1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408
	name = sample_flags_to_name(flags & ~PERF_IP_FLAG_IN_TX);
	if (name)
		return fprintf(fp, "  %-15s%4s ", name, in_tx ? "(x)" : "");

	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)
			return fprintf(fp, "  tr strt %-7s%4s ", name, in_tx ? "(x)" : "");
	}

	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)
			return fprintf(fp, "  tr end  %-7s%4s ", name, in_tx ? "(x)" : "");
1409 1410
	}

1411 1412 1413 1414 1415 1416 1417 1418 1419
	for (i = 0; i < n; i++, flags >>= 1) {
		if (flags & 1)
			str[pos++] = chars[i];
	}
	for (; i < 32; i++, flags >>= 1) {
		if (flags & 1)
			str[pos++] = '?';
	}
	str[pos] = 0;
1420

1421
	return fprintf(fp, "  %-19s ", str);
1422 1423
}

1424 1425 1426 1427 1428 1429
struct printer_data {
	int line_no;
	bool hit_nul;
	bool is_printable;
};

1430 1431 1432
static int sample__fprintf_bpf_output(enum binary_printer_ops op,
				      unsigned int val,
				      void *extra, FILE *fp)
1433 1434 1435
{
	unsigned char ch = (unsigned char)val;
	struct printer_data *printer_data = extra;
1436
	int printed = 0;
1437 1438 1439

	switch (op) {
	case BINARY_PRINT_DATA_BEGIN:
1440
		printed += fprintf(fp, "\n");
1441 1442
		break;
	case BINARY_PRINT_LINE_BEGIN:
1443
		printed += fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" :
1444 1445 1446
						        "           ");
		break;
	case BINARY_PRINT_ADDR:
1447
		printed += fprintf(fp, " %04x:", val);
1448 1449
		break;
	case BINARY_PRINT_NUM_DATA:
1450
		printed += fprintf(fp, " %02x", val);
1451 1452
		break;
	case BINARY_PRINT_NUM_PAD:
1453
		printed += fprintf(fp, "   ");
1454 1455
		break;
	case BINARY_PRINT_SEP:
1456
		printed += fprintf(fp, "  ");
1457 1458 1459 1460 1461 1462
		break;
	case BINARY_PRINT_CHAR_DATA:
		if (printer_data->hit_nul && ch)
			printer_data->is_printable = false;

		if (!isprint(ch)) {
1463
			printed += fprintf(fp, "%c", '.');
1464 1465 1466 1467 1468 1469 1470 1471 1472

			if (!printer_data->is_printable)
				break;

			if (ch == '\0')
				printer_data->hit_nul = true;
			else
				printer_data->is_printable = false;
		} else {
1473
			printed += fprintf(fp, "%c", ch);
1474 1475 1476
		}
		break;
	case BINARY_PRINT_CHAR_PAD:
1477
		printed += fprintf(fp, " ");
1478 1479
		break;
	case BINARY_PRINT_LINE_END:
1480
		printed += fprintf(fp, "\n");
1481 1482 1483 1484 1485 1486
		printer_data->line_no++;
		break;
	case BINARY_PRINT_DATA_END:
	default:
		break;
	}
1487 1488

	return printed;
1489 1490
}

1491
static int perf_sample__fprintf_bpf_output(struct perf_sample *sample, FILE *fp)
1492 1493 1494
{
	unsigned int nr_bytes = sample->raw_size;
	struct printer_data printer_data = {0, false, true};
1495 1496
	int printed = binary__fprintf(sample->raw_data, nr_bytes, 8,
				      sample__fprintf_bpf_output, &printer_data, fp);
1497 1498

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

	return printed;
1502 1503
}

1504
static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp)
1505 1506
{
	if (len > 0 && len < spacing)
1507 1508 1509
		return fprintf(fp, "%*s", spacing - len, "");

	return 0;
1510 1511
}

1512
static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)
1513
{
1514
	return perf_sample__fprintf_spacing(len, 34, fp);
1515 1516
}

1517
static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp)
1518 1519 1520 1521 1522
{
	struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
	int len;

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

1525
	len = fprintf(fp, " IP: %u payload: %#" PRIx64 " ",
1526
		     data->ip, le64_to_cpu(data->payload));
1527
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1528 1529
}

1530
static int perf_sample__fprintf_synth_mwait(struct perf_sample *sample, FILE *fp)
1531 1532 1533 1534 1535
{
	struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
	int len;

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

1538 1539 1540
	len = fprintf(fp, " hints: %#x extensions: %#x ",
		      data->hints, data->extensions);
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1541 1542
}

1543
static int perf_sample__fprintf_synth_pwre(struct perf_sample *sample, FILE *fp)
1544 1545 1546 1547 1548
{
	struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
	int len;

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

1551 1552 1553
	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);
1554 1555
}

1556
static int perf_sample__fprintf_synth_exstop(struct perf_sample *sample, FILE *fp)
1557 1558 1559 1560 1561
{
	struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
	int len;

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

1564 1565
	len = fprintf(fp, " IP: %u ", data->ip);
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1566 1567
}

1568
static int perf_sample__fprintf_synth_pwrx(struct perf_sample *sample, FILE *fp)
1569 1570 1571 1572 1573
{
	struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
	int len;

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

1576
	len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ",
1577 1578
		     data->deepest_cstate, data->last_cstate,
		     data->wake_reason);
1579
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1580 1581
}

1582
static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp)
1583 1584 1585 1586 1587 1588
{
	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))
1589
		return 0;
1590 1591

	freq = (le32_to_cpu(data->freq) + 500) / 1000;
1592
	len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
1593 1594
	if (data->max_nonturbo) {
		percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
1595
		len += fprintf(fp, "(%3u%%) ", percent);
1596
	}
1597
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1598 1599
}

1600
static int perf_sample__fprintf_synth(struct perf_sample *sample,
1601
				      struct evsel *evsel, FILE *fp)
1602
{
1603
	switch (evsel->core.attr.config) {
1604
	case PERF_SYNTH_INTEL_PTWRITE:
1605
		return perf_sample__fprintf_synth_ptwrite(sample, fp);
1606
	case PERF_SYNTH_INTEL_MWAIT:
1607
		return perf_sample__fprintf_synth_mwait(sample, fp);
1608
	case PERF_SYNTH_INTEL_PWRE:
1609
		return perf_sample__fprintf_synth_pwre(sample, fp);
1610
	case PERF_SYNTH_INTEL_EXSTOP:
1611
		return perf_sample__fprintf_synth_exstop(sample, fp);
1612
	case PERF_SYNTH_INTEL_PWRX:
1613
		return perf_sample__fprintf_synth_pwrx(sample, fp);
1614
	case PERF_SYNTH_INTEL_CBR:
1615
		return perf_sample__fprintf_synth_cbr(sample, fp);
1616 1617 1618
	default:
		break;
	}
1619 1620

	return 0;
1621 1622
}

1623 1624 1625 1626 1627 1628
struct perf_script {
	struct perf_tool	tool;
	struct perf_session	*session;
	bool			show_task_events;
	bool			show_mmap_events;
	bool			show_switch_events;
1629
	bool			show_namespace_events;
1630
	bool			show_lost_events;
1631
	bool			show_round_events;
1632
	bool			show_bpf_events;
1633
	bool			allocated;
1634
	bool			per_event_dump;
1635
	struct evswitch		evswitch;
1636
	struct perf_cpu_map	*cpus;
1637
	struct perf_thread_map *threads;
1638
	int			name_width;
1639
	const char              *time_str;
1640 1641
	struct perf_time_interval *ptime_range;
	int			range_size;
1642
	int			range_num;
1643 1644
};

1645
static int perf_evlist__max_name_len(struct evlist *evlist)
1646
{
1647
	struct evsel *evsel;
1648 1649
	int max = 0;

1650
	evlist__for_each_entry(evlist, evsel) {
1651 1652 1653 1654 1655 1656 1657 1658
		int len = strlen(perf_evsel__name(evsel));

		max = MAX(len, max);
	}

	return max;
}

1659
static int data_src__fprintf(u64 data_src, FILE *fp)
J
Jiri Olsa 已提交
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672
{
	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;

1673
	return fprintf(fp, "%-*s", maxlen, out);
J
Jiri Olsa 已提交
1674 1675
}

1676 1677 1678
struct metric_ctx {
	struct perf_sample	*sample;
	struct thread		*thread;
1679
	struct evsel	*evsel;
1680 1681 1682
	FILE 			*fp;
};

1683 1684
static void script_print_metric(struct perf_stat_config *config __maybe_unused,
				void *ctx, const char *color,
1685 1686 1687 1688 1689 1690 1691 1692
			        const char *fmt,
			        const char *unit, double val)
{
	struct metric_ctx *mctx = ctx;

	if (!fmt)
		return;
	perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel,
1693
				   PERF_RECORD_SAMPLE, mctx->fp);
1694 1695 1696 1697 1698 1699 1700 1701
	fputs("\tmetric: ", mctx->fp);
	if (color)
		color_fprintf(mctx->fp, color, fmt, val);
	else
		printf(fmt, val);
	fprintf(mctx->fp, " %s\n", unit);
}

1702 1703
static void script_new_line(struct perf_stat_config *config __maybe_unused,
			    void *ctx)
1704 1705 1706 1707
{
	struct metric_ctx *mctx = ctx;

	perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel,
1708
				   PERF_RECORD_SAMPLE, mctx->fp);
1709 1710 1711 1712 1713
	fputs("\tmetric: ", mctx->fp);
}

static void perf_sample__fprint_metric(struct perf_script *script,
				       struct thread *thread,
1714
				       struct evsel *evsel,
1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728
				       struct perf_sample *sample,
				       FILE *fp)
{
	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,
	};
1729
	struct evsel *ev2;
1730 1731 1732 1733 1734 1735 1736 1737 1738
	u64 val;

	if (!evsel->stats)
		perf_evlist__alloc_stats(script->session->evlist, false);
	if (evsel_script(evsel->leader)->gnum++ == 0)
		perf_stat__reset_shadow_stats();
	val = sample->period * evsel->scale;
	perf_stat__update_shadow_stats(evsel,
				       val,
1739 1740
				       sample->cpu,
				       &rt_stat);
1741
	evsel_script(evsel)->val = val;
1742
	if (evsel_script(evsel->leader)->gnum == evsel->leader->core.nr_members) {
1743
		for_each_group_member (ev2, evsel->leader) {
1744
			perf_stat__print_shadow_stats(&stat_config, ev2,
1745 1746 1747
						      evsel_script(ev2)->val,
						      sample->cpu,
						      &ctx,
J
Jin Yao 已提交
1748 1749
						      NULL,
						      &rt_stat);
1750 1751 1752 1753 1754
		}
		evsel_script(evsel->leader)->gnum = 0;
	}
}

1755
static bool show_event(struct perf_sample *sample,
1756
		       struct evsel *evsel,
1757 1758 1759
		       struct thread *thread,
		       struct addr_location *al)
{
1760
	int depth = thread_stack__depth(thread, sample->cpu);
1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795

	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;
		const char *name = resolve_branch_sym(sample, evsel, thread, al,
				&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;
	}
}

1796
static void process_event(struct perf_script *script,
1797
			  struct perf_sample *sample, struct evsel *evsel,
1798 1799
			  struct addr_location *al,
			  struct machine *machine)
1800
{
1801
	struct thread *thread = al->thread;
1802
	struct perf_event_attr *attr = &evsel->core.attr;
1803
	unsigned int type = output_type(attr->type);
1804
	struct evsel_script *es = evsel->priv;
1805
	FILE *fp = es->fp;
1806

1807
	if (output[type].fields == 0)
1808 1809
		return;

1810 1811 1812
	if (!show_event(sample, evsel, thread, al))
		return;

1813 1814
	if (evswitch__discard(&script->evswitch, evsel))
		return;
1815

1816 1817
	++es->samples;

1818 1819
	perf_sample__fprintf_start(sample, thread, evsel,
				   PERF_RECORD_SAMPLE, fp);
1820

J
Jiri Olsa 已提交
1821
	if (PRINT_FIELD(PERIOD))
1822
		fprintf(fp, "%10" PRIu64 " ", sample->period);
J
Jiri Olsa 已提交
1823

1824 1825
	if (PRINT_FIELD(EVNAME)) {
		const char *evname = perf_evsel__name(evsel);
1826 1827 1828 1829

		if (!script->name_width)
			script->name_width = perf_evlist__max_name_len(script->session->evlist);

1830
		fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]");
1831 1832
	}

1833
	if (print_flags)
1834
		perf_sample__fprintf_flags(sample->flags, fp);
1835

1836
	if (is_bts_event(attr)) {
1837
		perf_sample__fprintf_bts(sample, evsel, thread, al, machine, fp);
1838 1839 1840
		return;
	}

1841
	if (PRINT_FIELD(TRACE) && sample->raw_data) {
1842 1843 1844
		event_format__fprintf(evsel->tp_format, sample->cpu,
				      sample->raw_data, sample->raw_size, fp);
	}
1845 1846

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

1849
	if (PRINT_FIELD(ADDR))
1850
		perf_sample__fprintf_addr(sample, thread, attr, fp);
1851

1852
	if (PRINT_FIELD(DATA_SRC))
1853
		data_src__fprintf(sample->data_src, fp);
1854 1855

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

1858
	if (PRINT_FIELD(IP)) {
1859
		struct callchain_cursor *cursor = NULL;
1860

1861
		if (symbol_conf.use_callchain && sample->callchain &&
1862
		    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
1863
					      sample, NULL, NULL, scripting_max_stack) == 0)
1864
			cursor = &callchain_cursor;
1865

1866 1867
		fputc(cursor ? '\n' : ' ', fp);
		sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, fp);
1868 1869
	}

1870
	if (PRINT_FIELD(IREGS))
1871
		perf_sample__fprintf_iregs(sample, attr, fp);
1872

A
Andi Kleen 已提交
1873
	if (PRINT_FIELD(UREGS))
1874
		perf_sample__fprintf_uregs(sample, attr, fp);
A
Andi Kleen 已提交
1875

1876
	if (PRINT_FIELD(BRSTACK))
1877
		perf_sample__fprintf_brstack(sample, thread, attr, fp);
1878
	else if (PRINT_FIELD(BRSTACKSYM))
1879
		perf_sample__fprintf_brstacksym(sample, thread, attr, fp);
1880
	else if (PRINT_FIELD(BRSTACKOFF))
1881
		perf_sample__fprintf_brstackoff(sample, thread, attr, fp);
1882

1883
	if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
1884 1885
		perf_sample__fprintf_bpf_output(sample, fp);
	perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
1886 1887

	if (PRINT_FIELD(PHYS_ADDR))
1888
		fprintf(fp, "%16" PRIx64, sample->phys_addr);
1889 1890 1891

	perf_sample__fprintf_ipc(sample, attr, fp);

1892
	fprintf(fp, "\n");
1893

A
Andi Kleen 已提交
1894 1895 1896 1897 1898 1899
	if (PRINT_FIELD(SRCCODE)) {
		if (map__fprintf_srccode(al->map, al->addr, stdout,
					 &thread->srccode_state))
			printf("\n");
	}

1900 1901
	if (PRINT_FIELD(METRIC))
		perf_sample__fprint_metric(script, thread, evsel, sample, fp);
1902 1903 1904

	if (verbose)
		fflush(fp);
1905 1906
}

T
Tom Zanussi 已提交
1907 1908
static struct scripting_ops	*scripting_ops;

1909
static void __process_stat(struct evsel *counter, u64 tstamp)
1910
{
1911
	int nthreads = perf_thread_map__nr(counter->core.threads);
1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931
	int ncpus = perf_evsel__nr_cpus(counter);
	int cpu, thread;
	static int header_printed;

	if (counter->system_wide)
		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",
1932
				counter->core.cpus->map[cpu],
1933
				perf_thread_map__pid(counter->core.threads, thread),
1934 1935 1936 1937 1938 1939 1940 1941 1942
				counts->val,
				counts->ena,
				counts->run,
				tstamp,
				perf_evsel__name(counter));
		}
	}
}

1943
static void process_stat(struct evsel *counter, u64 tstamp)
1944 1945 1946
{
	if (scripting_ops && scripting_ops->process_stat)
		scripting_ops->process_stat(&stat_config, counter, tstamp);
1947 1948
	else
		__process_stat(counter, tstamp);
1949 1950 1951 1952 1953 1954 1955 1956
}

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

T
Tom Zanussi 已提交
1957 1958
static void setup_scripting(void)
{
1959
	setup_perl_scripting();
1960
	setup_python_scripting();
T
Tom Zanussi 已提交
1961 1962
}

1963 1964
static int flush_scripting(void)
{
1965
	return scripting_ops ? scripting_ops->flush_script() : 0;
1966 1967
}

T
Tom Zanussi 已提交
1968 1969
static int cleanup_scripting(void)
{
1970
	pr_debug("\nperf script stopped\n");
1971

1972
	return scripting_ops ? scripting_ops->stop_script() : 0;
T
Tom Zanussi 已提交
1973 1974
}

1975 1976 1977 1978 1979 1980 1981
static bool filter_cpu(struct perf_sample *sample)
{
	if (cpu_list)
		return !test_bit(sample->cpu, cpu_bitmap);
	return false;
}

1982
static int process_sample_event(struct perf_tool *tool,
1983
				union perf_event *event,
1984
				struct perf_sample *sample,
1985
				struct evsel *evsel,
1986
				struct machine *machine)
F
Frederic Weisbecker 已提交
1987
{
1988
	struct perf_script *scr = container_of(tool, struct perf_script, tool);
1989
	struct addr_location al;
F
Frederic Weisbecker 已提交
1990

1991 1992
	if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num,
					  sample->time)) {
1993
		return 0;
1994
	}
1995

1996 1997 1998 1999 2000 2001
	if (debug_mode) {
		if (sample->time < last_timestamp) {
			pr_err("Samples misordered, previous: %" PRIu64
				" this: %" PRIu64 "\n", last_timestamp,
				sample->time);
			nr_unordered++;
2002
		}
2003 2004
		last_timestamp = sample->time;
		return 0;
F
Frederic Weisbecker 已提交
2005
	}
2006

2007
	if (machine__resolve(machine, &al, sample) < 0) {
2008 2009 2010 2011 2012 2013
		pr_err("problem processing %d event, skipping it.\n",
		       event->header.type);
		return -1;
	}

	if (al.filtered)
2014
		goto out_put;
2015

2016
	if (filter_cpu(sample))
2017
		goto out_put;
2018

2019 2020 2021
	if (scripting_ops)
		scripting_ops->process_event(event, sample, evsel, &al);
	else
2022
		process_event(scr, sample, evsel, &al, machine);
2023

2024 2025
out_put:
	addr_location__put(&al);
F
Frederic Weisbecker 已提交
2026 2027 2028
	return 0;
}

2029
static int process_attr(struct perf_tool *tool, union perf_event *event,
2030
			struct evlist **pevlist)
2031 2032
{
	struct perf_script *scr = container_of(tool, struct perf_script, tool);
2033
	struct evlist *evlist;
2034
	struct evsel *evsel, *pos;
2035
	int err;
2036
	static struct evsel_script *es;
2037 2038 2039 2040 2041 2042 2043 2044

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

	evlist = *pevlist;
	evsel = perf_evlist__last(*pevlist);

2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057
	if (!evsel->priv) {
		if (scr->per_event_dump) {
			evsel->priv = perf_evsel_script__new(evsel,
						scr->session->data);
		} else {
			es = zalloc(sizeof(*es));
			if (!es)
				return -ENOMEM;
			es->fp = stdout;
			evsel->priv = es;
		}
	}

2058 2059
	if (evsel->core.attr.type >= PERF_TYPE_MAX &&
	    evsel->core.attr.type != PERF_TYPE_SYNTH)
2060 2061
		return 0;

2062
	evlist__for_each_entry(evlist, pos) {
2063
		if (pos->core.attr.type == evsel->core.attr.type && pos != evsel)
2064 2065 2066
			return 0;
	}

2067
	set_print_ip_opts(&evsel->core.attr);
2068

2069
	if (evsel->core.attr.sample_type)
2070 2071 2072
		err = perf_evsel__check_attr(evsel, scr->session);

	return err;
2073 2074
}

2075 2076 2077 2078 2079 2080 2081 2082
static int process_comm_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
	struct thread *thread;
	struct perf_script *script = container_of(tool, struct perf_script, tool);
	struct perf_session *session = script->session;
2083
	struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094
	int ret = -1;

	thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid);
	if (thread == NULL) {
		pr_debug("problem processing COMM event, skipping it.\n");
		return -1;
	}

	if (perf_event__process_comm(tool, event, sample, machine) < 0)
		goto out;

2095
	if (!evsel->core.attr.sample_id_all) {
2096 2097 2098 2099 2100
		sample->cpu = 0;
		sample->time = 0;
		sample->tid = event->comm.tid;
		sample->pid = event->comm.pid;
	}
2101 2102
	if (!filter_cpu(sample)) {
		perf_sample__fprintf_start(sample, thread, evsel,
2103
				   PERF_RECORD_COMM, stdout);
2104 2105
		perf_event__fprintf(event, stdout);
	}
2106 2107
	ret = 0;
out:
2108
	thread__put(thread);
2109 2110 2111
	return ret;
}

2112 2113 2114 2115 2116 2117 2118 2119
static int process_namespaces_event(struct perf_tool *tool,
				    union perf_event *event,
				    struct perf_sample *sample,
				    struct machine *machine)
{
	struct thread *thread;
	struct perf_script *script = container_of(tool, struct perf_script, tool);
	struct perf_session *session = script->session;
2120
	struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132
	int ret = -1;

	thread = machine__findnew_thread(machine, event->namespaces.pid,
					 event->namespaces.tid);
	if (thread == NULL) {
		pr_debug("problem processing NAMESPACES event, skipping it.\n");
		return -1;
	}

	if (perf_event__process_namespaces(tool, event, sample, machine) < 0)
		goto out;

2133
	if (!evsel->core.attr.sample_id_all) {
2134 2135 2136 2137 2138
		sample->cpu = 0;
		sample->time = 0;
		sample->tid = event->namespaces.tid;
		sample->pid = event->namespaces.pid;
	}
2139 2140 2141 2142 2143
	if (!filter_cpu(sample)) {
		perf_sample__fprintf_start(sample, thread, evsel,
					   PERF_RECORD_NAMESPACES, stdout);
		perf_event__fprintf(event, stdout);
	}
2144 2145 2146 2147 2148 2149
	ret = 0;
out:
	thread__put(thread);
	return ret;
}

2150 2151 2152 2153 2154 2155 2156 2157
static int process_fork_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
	struct thread *thread;
	struct perf_script *script = container_of(tool, struct perf_script, tool);
	struct perf_session *session = script->session;
2158
	struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2159 2160 2161 2162 2163 2164 2165 2166 2167 2168

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

	thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid);
	if (thread == NULL) {
		pr_debug("problem processing FORK event, skipping it.\n");
		return -1;
	}

2169
	if (!evsel->core.attr.sample_id_all) {
2170 2171 2172 2173 2174
		sample->cpu = 0;
		sample->time = event->fork.time;
		sample->tid = event->fork.tid;
		sample->pid = event->fork.pid;
	}
2175 2176 2177 2178 2179
	if (!filter_cpu(sample)) {
		perf_sample__fprintf_start(sample, thread, evsel,
					   PERF_RECORD_FORK, stdout);
		perf_event__fprintf(event, stdout);
	}
2180
	thread__put(thread);
2181 2182 2183 2184 2185 2186 2187 2188

	return 0;
}
static int process_exit_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
2189
	int err = 0;
2190 2191 2192
	struct thread *thread;
	struct perf_script *script = container_of(tool, struct perf_script, tool);
	struct perf_session *session = script->session;
2193
	struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2194 2195 2196 2197 2198 2199 2200

	thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid);
	if (thread == NULL) {
		pr_debug("problem processing EXIT event, skipping it.\n");
		return -1;
	}

2201
	if (!evsel->core.attr.sample_id_all) {
2202 2203
		sample->cpu = 0;
		sample->time = 0;
2204 2205
		sample->tid = event->fork.tid;
		sample->pid = event->fork.pid;
2206
	}
2207 2208 2209 2210 2211
	if (!filter_cpu(sample)) {
		perf_sample__fprintf_start(sample, thread, evsel,
					   PERF_RECORD_EXIT, stdout);
		perf_event__fprintf(event, stdout);
	}
2212 2213

	if (perf_event__process_exit(tool, event, sample, machine) < 0)
2214
		err = -1;
2215

2216 2217
	thread__put(thread);
	return err;
2218 2219
}

2220 2221 2222 2223 2224 2225 2226 2227
static int process_mmap_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
	struct thread *thread;
	struct perf_script *script = container_of(tool, struct perf_script, tool);
	struct perf_session *session = script->session;
2228
	struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2229 2230 2231 2232 2233 2234 2235 2236 2237 2238

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

	thread = machine__findnew_thread(machine, event->mmap.pid, event->mmap.tid);
	if (thread == NULL) {
		pr_debug("problem processing MMAP event, skipping it.\n");
		return -1;
	}

2239
	if (!evsel->core.attr.sample_id_all) {
2240 2241 2242 2243 2244
		sample->cpu = 0;
		sample->time = 0;
		sample->tid = event->mmap.tid;
		sample->pid = event->mmap.pid;
	}
2245 2246 2247 2248 2249
	if (!filter_cpu(sample)) {
		perf_sample__fprintf_start(sample, thread, evsel,
					   PERF_RECORD_MMAP, stdout);
		perf_event__fprintf(event, stdout);
	}
2250
	thread__put(thread);
2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261
	return 0;
}

static int process_mmap2_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
	struct thread *thread;
	struct perf_script *script = container_of(tool, struct perf_script, tool);
	struct perf_session *session = script->session;
2262
	struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2263 2264 2265 2266 2267 2268 2269 2270 2271 2272

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

	thread = machine__findnew_thread(machine, event->mmap2.pid, event->mmap2.tid);
	if (thread == NULL) {
		pr_debug("problem processing MMAP2 event, skipping it.\n");
		return -1;
	}

2273
	if (!evsel->core.attr.sample_id_all) {
2274 2275 2276 2277 2278
		sample->cpu = 0;
		sample->time = 0;
		sample->tid = event->mmap2.tid;
		sample->pid = event->mmap2.pid;
	}
2279 2280 2281 2282 2283
	if (!filter_cpu(sample)) {
		perf_sample__fprintf_start(sample, thread, evsel,
					   PERF_RECORD_MMAP2, stdout);
		perf_event__fprintf(event, stdout);
	}
2284
	thread__put(thread);
2285 2286 2287
	return 0;
}

2288 2289 2290 2291 2292 2293 2294 2295
static int process_switch_event(struct perf_tool *tool,
				union perf_event *event,
				struct perf_sample *sample,
				struct machine *machine)
{
	struct thread *thread;
	struct perf_script *script = container_of(tool, struct perf_script, tool);
	struct perf_session *session = script->session;
2296
	struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2297 2298 2299 2300

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

2301 2302 2303 2304 2305 2306
	if (scripting_ops && scripting_ops->process_switch)
		scripting_ops->process_switch(event, sample, machine);

	if (!script->show_switch_events)
		return 0;

2307 2308 2309 2310 2311 2312 2313
	thread = machine__findnew_thread(machine, sample->pid,
					 sample->tid);
	if (thread == NULL) {
		pr_debug("problem processing SWITCH event, skipping it.\n");
		return -1;
	}

2314 2315 2316 2317 2318
	if (!filter_cpu(sample)) {
		perf_sample__fprintf_start(sample, thread, evsel,
					   PERF_RECORD_SWITCH, stdout);
		perf_event__fprintf(event, stdout);
	}
2319 2320 2321 2322
	thread__put(thread);
	return 0;
}

2323 2324 2325 2326 2327 2328 2329 2330
static int
process_lost_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);
	struct perf_session *session = script->session;
2331
	struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2332 2333 2334 2335 2336 2337 2338
	struct thread *thread;

	thread = machine__findnew_thread(machine, sample->pid,
					 sample->tid);
	if (thread == NULL)
		return -1;

2339 2340 2341 2342 2343
	if (!filter_cpu(sample)) {
		perf_sample__fprintf_start(sample, thread, evsel,
					   PERF_RECORD_LOST, stdout);
		perf_event__fprintf(event, stdout);
	}
2344 2345 2346 2347
	thread__put(thread);
	return 0;
}

2348 2349 2350 2351 2352 2353 2354 2355 2356 2357
static int
process_finished_round_event(struct perf_tool *tool __maybe_unused,
			     union perf_event *event,
			     struct ordered_events *oe __maybe_unused)

{
	perf_event__fprintf(event, stdout);
	return 0;
}

2358 2359 2360 2361 2362 2363 2364 2365 2366
static int
process_bpf_events(struct perf_tool *tool __maybe_unused,
		   union perf_event *event,
		   struct perf_sample *sample,
		   struct machine *machine)
{
	struct thread *thread;
	struct perf_script *script = container_of(tool, struct perf_script, tool);
	struct perf_session *session = script->session;
2367
	struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2368 2369 2370 2371

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

2372
	if (!evsel->core.attr.sample_id_all) {
2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392
		perf_event__fprintf(event, stdout);
		return 0;
	}

	thread = machine__findnew_thread(machine, sample->pid, sample->tid);
	if (thread == NULL) {
		pr_debug("problem processing MMAP event, skipping it.\n");
		return -1;
	}

	if (!filter_cpu(sample)) {
		perf_sample__fprintf_start(sample, thread, evsel,
					   event->header.type, stdout);
		perf_event__fprintf(event, stdout);
	}

	thread__put(thread);
	return 0;
}

2393
static void sig_handler(int sig __maybe_unused)
2394 2395 2396 2397
{
	session_done = 1;
}

2398 2399
static void perf_script__fclose_per_event_dump(struct perf_script *script)
{
2400
	struct evlist *evlist = script->session->evlist;
2401
	struct evsel *evsel;
2402 2403 2404 2405

	evlist__for_each_entry(evlist, evsel) {
		if (!evsel->priv)
			break;
2406
		perf_evsel_script__delete(evsel->priv);
2407 2408 2409 2410 2411 2412
		evsel->priv = NULL;
	}
}

static int perf_script__fopen_per_event_dump(struct perf_script *script)
{
2413
	struct evsel *evsel;
2414 2415

	evlist__for_each_entry(script->session->evlist, evsel) {
2416 2417 2418 2419 2420 2421 2422 2423 2424 2425
		/*
		 * Already setup? I.e. we may be called twice in cases like
		 * Intel PT, one for the intel_pt// and dummy events, then
		 * for the evsels syntheized from the auxtrace info.
		 *
		 * Ses perf_script__process_auxtrace_info.
		 */
		if (evsel->priv != NULL)
			continue;

2426
		evsel->priv = perf_evsel_script__new(evsel, script->session->data);
2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439
		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)
{
2440 2441
	struct evsel *evsel;
	static struct evsel_script es_stdout;
2442 2443 2444 2445

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

2446 2447
	es_stdout.fp = stdout;

2448
	evlist__for_each_entry(script->session->evlist, evsel)
2449
		evsel->priv = &es_stdout;
2450 2451 2452 2453

	return 0;
}

2454 2455
static void perf_script__exit_per_event_dump_stats(struct perf_script *script)
{
2456
	struct evsel *evsel;
2457 2458

	evlist__for_each_entry(script->session->evlist, evsel) {
2459
		struct evsel_script *es = evsel->priv;
2460 2461 2462 2463 2464 2465 2466

		perf_evsel_script__fprintf(es, stdout);
		perf_evsel_script__delete(es);
		evsel->priv = NULL;
	}
}

2467
static int __cmd_script(struct perf_script *script)
F
Frederic Weisbecker 已提交
2468
{
2469 2470
	int ret;

2471 2472
	signal(SIGINT, sig_handler);

2473 2474
	perf_stat__init_shadow_stats();

2475 2476 2477 2478 2479 2480
	/* 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;
	}
2481 2482 2483 2484
	if (script->show_mmap_events) {
		script->tool.mmap = process_mmap_event;
		script->tool.mmap2 = process_mmap2_event;
	}
2485
	if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch))
2486
		script->tool.context_switch = process_switch_event;
2487 2488
	if (script->show_namespace_events)
		script->tool.namespaces = process_namespaces_event;
2489 2490
	if (script->show_lost_events)
		script->tool.lost = process_lost_event;
2491 2492 2493 2494
	if (script->show_round_events) {
		script->tool.ordered_events = false;
		script->tool.finished_round = process_finished_round_event;
	}
2495
	if (script->show_bpf_events) {
2496 2497
		script->tool.ksymbol = process_bpf_events;
		script->tool.bpf     = process_bpf_events;
2498
	}
2499

2500 2501 2502 2503 2504
	if (perf_script__setup_per_event_dump(script)) {
		pr_err("Couldn't create the per event dump files\n");
		return -1;
	}

2505
	ret = perf_session__process_events(script->session);
2506

2507
	if (script->per_event_dump)
2508
		perf_script__exit_per_event_dump_stats(script);
2509

2510
	if (debug_mode)
2511
		pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
2512 2513

	return ret;
F
Frederic Weisbecker 已提交
2514 2515
}

T
Tom Zanussi 已提交
2516 2517 2518 2519 2520 2521
struct script_spec {
	struct list_head	node;
	struct scripting_ops	*ops;
	char			spec[0];
};

2522
static LIST_HEAD(script_specs);
T
Tom Zanussi 已提交
2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559

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;

2560
	s = script_spec__new(spec, ops);
T
Tom Zanussi 已提交
2561 2562
	if (!s)
		return -1;
2563 2564
	else
		script_spec__add(s);
T
Tom Zanussi 已提交
2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583

	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 "
2584
		"perf script -s [spec:]script.[spec]):\n\n");
T
Tom Zanussi 已提交
2585 2586 2587 2588 2589 2590 2591

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

	fprintf(stderr, "\n");
}

2592 2593
static int parse_scriptname(const struct option *opt __maybe_unused,
			    const char *str, int unset __maybe_unused)
T
Tom Zanussi 已提交
2594 2595 2596 2597 2598
{
	char spec[PATH_MAX];
	const char *script, *ext;
	int len;

2599
	if (strcmp(str, "lang") == 0) {
T
Tom Zanussi 已提交
2600
		list_available_languages();
2601
		exit(0);
T
Tom Zanussi 已提交
2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620
	}

	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;
2621
		ext = strrchr(script, '.');
T
Tom Zanussi 已提交
2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637
		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;
		}
	}

	script_name = strdup(script);

	return 0;
}

2638 2639
static int parse_output_fields(const struct option *opt __maybe_unused,
			    const char *arg, int unset __maybe_unused)
2640
{
2641
	char *tok, *strtok_saveptr = NULL;
2642
	int i, imax = ARRAY_SIZE(all_output_options);
2643
	int j;
2644 2645
	int rc = 0;
	char *str = strdup(arg);
2646
	int type = -1;
2647
	enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;
2648 2649 2650 2651

	if (!str)
		return -ENOMEM;

2652 2653 2654
	/* 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.
2655
	 */
2656 2657 2658 2659 2660 2661 2662 2663 2664 2665
	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;
2666 2667
		else if (!strcmp(str, "raw"))
			type = PERF_TYPE_RAW;
2668 2669
		else if (!strcmp(str, "break"))
			type = PERF_TYPE_BREAKPOINT;
2670 2671
		else if (!strcmp(str, "synth"))
			type = OUTPUT_TYPE_SYNTH;
2672 2673
		else {
			fprintf(stderr, "Invalid event type in field string.\n");
2674 2675
			rc = -EINVAL;
			goto out;
2676 2677 2678 2679 2680 2681
		}

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

2682 2683 2684 2685
		/* Don't override defaults for +- */
		if (strchr(tok, '+') || strchr(tok, '-'))
			goto parse;

2686 2687
		output[type].fields = 0;
		output[type].user_set = true;
2688
		output[type].wildcard_set = false;
2689 2690 2691 2692 2693 2694 2695 2696 2697 2698

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

2699 2700 2701 2702
		/* Don't override defaults for +- */
		if (strchr(str, '+') || strchr(str, '-'))
			goto parse;

2703 2704 2705
		if (output_set_by_user())
			pr_warning("Overriding previous field request for all events.\n");

2706
		for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2707 2708
			output[j].fields = 0;
			output[j].user_set = true;
2709
			output[j].wildcard_set = true;
2710
		}
2711 2712
	}

2713
parse:
2714
	for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730
		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;
		}

2731
		for (i = 0; i < imax; ++i) {
2732
			if (strcmp(tok, all_output_options[i].str) == 0)
2733 2734
				break;
		}
2735
		if (i == imax && strcmp(tok, "flags") == 0) {
2736
			print_flags = change == REMOVE ? false : true;
2737 2738
			continue;
		}
2739
		if (i == imax) {
2740
			fprintf(stderr, "Invalid field requested.\n");
2741
			rc = -EINVAL;
2742
			goto out;
2743 2744
		}

2745 2746 2747 2748
		if (type == -1) {
			/* add user option to all events types for
			 * which it is valid
			 */
2749
			for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2750 2751 2752
				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));
2753
				} else {
2754
					if (change == REMOVE) {
2755
						output[j].fields &= ~all_output_options[i].field;
2756 2757
						output[j].user_set_fields &= ~all_output_options[i].field;
					} else {
2758
						output[j].fields |= all_output_options[i].field;
2759 2760
						output[j].user_set_fields |= all_output_options[i].field;
					}
2761 2762
					output[j].user_set = true;
					output[j].wildcard_set = true;
2763
				}
2764 2765 2766 2767 2768 2769 2770 2771 2772
			}
		} 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;
			}
2773 2774 2775 2776
			if (change == REMOVE)
				output[type].fields &= ~all_output_options[i].field;
			else
				output[type].fields |= all_output_options[i].field;
2777 2778
			output[type].user_set = true;
			output[type].wildcard_set = true;
2779
		}
2780 2781
	}

2782 2783 2784 2785 2786 2787
	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));
		}
	}
2788
	goto out;
2789

2790 2791 2792
out_badmix:
	fprintf(stderr, "Cannot mix +-field with overridden fields\n");
	rc = -EINVAL;
2793
out:
2794 2795 2796 2797
	free(str);
	return rc;
}

2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810
#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)))
2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822


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

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

2823
static LIST_HEAD(script_descs);
2824 2825 2826 2827 2828

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

2829
	if (s != NULL && name)
2830 2831 2832 2833 2834 2835 2836
		s->name = strdup(name);

	return s;
}

static void script_desc__delete(struct script_desc *s)
{
2837 2838 2839
	zfree(&s->name);
	zfree(&s->half_liner);
	zfree(&s->args);
2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866
	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)
2867
		return NULL;
2868 2869 2870 2871 2872 2873

	script_desc__add(s);

	return s;
}

2874
static const char *ends_with(const char *str, const char *suffix)
2875 2876
{
	size_t suffix_len = strlen(suffix);
2877
	const char *p = str;
2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897

	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)) {
2898
		p = skip_spaces(line);
2899 2900 2901 2902 2903 2904 2905 2906
		if (strlen(p) == 0)
			continue;
		if (*p != '#')
			continue;
		p++;
		if (strlen(p) && *p == '!')
			continue;

2907
		p = skip_spaces(p);
2908 2909 2910 2911 2912
		if (strlen(p) && p[strlen(p) - 1] == '\n')
			p[strlen(p) - 1] = '\0';

		if (!strncmp(p, "description:", strlen("description:"))) {
			p += strlen("description:");
2913
			desc->half_liner = strdup(skip_spaces(p));
2914 2915 2916 2917 2918
			continue;
		}

		if (!strncmp(p, "args:", strlen("args:"))) {
			p += strlen("args:");
2919
			desc->args = strdup(skip_spaces(p));
2920 2921 2922 2923 2924 2925 2926 2927 2928
			continue;
		}
	}

	fclose(fp);

	return 0;
}

2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946
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;
}

2947 2948 2949
static int list_available_scripts(const struct option *opt __maybe_unused,
				  const char *s __maybe_unused,
				  int unset __maybe_unused)
2950
{
2951
	struct dirent *script_dirent, *lang_dirent;
2952 2953 2954 2955 2956 2957 2958 2959
	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;

2960
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
2961 2962

	scripts_dir = opendir(scripts_path);
2963 2964 2965 2966 2967 2968 2969
	if (!scripts_dir) {
		fprintf(stdout,
			"open(%s) failed.\n"
			"Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",
			scripts_path);
		exit(-1);
	}
2970

2971
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
2972 2973
		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
			  lang_dirent->d_name);
2974 2975 2976 2977
		lang_dir = opendir(lang_path);
		if (!lang_dir)
			continue;

2978 2979
		for_each_script(lang_path, lang_dir, script_dirent) {
			script_root = get_script_root(script_dirent, REPORT_SUFFIX);
2980
			if (script_root) {
2981
				desc = script_desc__findnew(script_root);
2982 2983
				scnprintf(script_path, MAXPATHLEN, "%s/%s",
					  lang_path, script_dirent->d_name);
2984
				read_script_info(desc, script_path);
2985
				free(script_root);
2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000
			}
		}
	}

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

3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014
/*
 * 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
 * cover the future complexing formats like event groups etc.
 */
static int check_ev_match(char *dir_name, char *scriptname,
			struct perf_session *session)
{
	char filename[MAXPATHLEN], evname[128];
	char line[BUFSIZ], *p;
3015
	struct evsel *pos;
3016 3017 3018
	int match, len;
	FILE *fp;

3019
	scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname);
3020 3021 3022 3023 3024 3025

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

	while (fgets(line, sizeof(line), fp)) {
3026
		p = skip_spaces(line);
3027 3028 3029 3030 3031 3032 3033 3034 3035
		if (*p == '#')
			continue;

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

			p += 2;
3036
			p = skip_spaces(p);
3037 3038 3039 3040 3041 3042 3043
			len = strcspn(p, " \t");
			if (!len)
				break;

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

			match = 0;
3044
			evlist__for_each_entry(session->evlist, pos) {
3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061
				if (!strcmp(perf_evsel__name(pos), evname)) {
					match = 1;
					break;
				}
			}

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

	fclose(fp);
	return 0;
}

3062 3063 3064 3065 3066 3067 3068
/*
 * 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.
 */
3069 3070
int find_scripts(char **scripts_array, char **scripts_path_array, int num,
		 int pathlen)
3071
{
3072
	struct dirent *script_dirent, *lang_dirent;
3073
	char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
3074
	DIR *scripts_dir, *lang_dir;
3075
	struct perf_session *session;
3076
	struct perf_data data = {
J
Jiri Olsa 已提交
3077 3078
		.path = input_name,
		.mode = PERF_DATA_MODE_READ,
3079
	};
3080 3081 3082
	char *temp;
	int i = 0;

3083
	session = perf_session__new(&data, false, NULL);
3084 3085 3086
	if (!session)
		return -1;

3087
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3088 3089

	scripts_dir = opendir(scripts_path);
3090 3091
	if (!scripts_dir) {
		perf_session__delete(session);
3092
		return -1;
3093
	}
3094

3095
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
3096 3097
		scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
			  lang_dirent->d_name);
3098
#ifndef HAVE_LIBPERL_SUPPORT
3099 3100 3101
		if (strstr(lang_path, "perl"))
			continue;
#endif
3102
#ifndef HAVE_LIBPYTHON_SUPPORT
3103 3104 3105 3106 3107 3108 3109 3110
		if (strstr(lang_path, "python"))
			continue;
#endif

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

3111
		for_each_script(lang_path, lang_dir, script_dirent) {
3112
			/* Skip those real time scripts: xxxtop.p[yl] */
3113
			if (strstr(script_dirent->d_name, "top."))
3114
				continue;
3115 3116 3117 3118
			if (i >= num)
				break;
			snprintf(scripts_path_array[i], pathlen, "%s/%s",
				lang_path,
3119 3120
				script_dirent->d_name);
			temp = strchr(script_dirent->d_name, '.');
3121
			snprintf(scripts_array[i],
3122 3123
				(temp - script_dirent->d_name) + 1,
				"%s", script_dirent->d_name);
3124 3125 3126 3127 3128

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

3129 3130
			i++;
		}
3131
		closedir(lang_dir);
3132 3133
	}

3134 3135
	closedir(scripts_dir);
	perf_session__delete(session);
3136 3137 3138
	return i;
}

3139 3140
static char *get_script_path(const char *script_root, const char *suffix)
{
3141
	struct dirent *script_dirent, *lang_dirent;
3142 3143 3144 3145
	char scripts_path[MAXPATHLEN];
	char script_path[MAXPATHLEN];
	DIR *scripts_dir, *lang_dir;
	char lang_path[MAXPATHLEN];
3146
	char *__script_root;
3147

3148
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3149 3150 3151 3152 3153

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

3154
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
3155 3156
		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
			  lang_dirent->d_name);
3157 3158 3159 3160
		lang_dir = opendir(lang_path);
		if (!lang_dir)
			continue;

3161 3162
		for_each_script(lang_path, lang_dir, script_dirent) {
			__script_root = get_script_root(script_dirent, suffix);
3163 3164
			if (__script_root && !strcmp(script_root, __script_root)) {
				free(__script_root);
3165 3166
				closedir(lang_dir);
				closedir(scripts_dir);
3167 3168
				scnprintf(script_path, MAXPATHLEN, "%s/%s",
					  lang_path, script_dirent->d_name);
3169
				return strdup(script_path);
3170 3171 3172
			}
			free(__script_root);
		}
3173
		closedir(lang_dir);
3174
	}
3175
	closedir(scripts_dir);
3176

3177
	return NULL;
3178 3179
}

3180 3181
static bool is_top_script(const char *script_path)
{
3182
	return ends_with(script_path, "top") == NULL ? false : true;
3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207
}

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

3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220
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 已提交
3221

3222 3223 3224 3225 3226
	system_wide = (argc == 0);

	return 0;
}

3227 3228 3229 3230 3231 3232 3233
static void script__setup_sample_type(struct perf_script *script)
{
	struct perf_session *session = script->session;
	u64 sample_type = perf_evlist__combined_sample_type(session->evlist);

	if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
		if ((sample_type & PERF_SAMPLE_REGS_USER) &&
3234
		    (sample_type & PERF_SAMPLE_STACK_USER)) {
3235
			callchain_param.record_mode = CALLCHAIN_DWARF;
3236 3237
			dwarf_callchain_users = true;
		} else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
3238 3239 3240 3241 3242 3243
			callchain_param.record_mode = CALLCHAIN_LBR;
		else
			callchain_param.record_mode = CALLCHAIN_FP;
	}
}

3244 3245
static int process_stat_round_event(struct perf_session *session,
				    union perf_event *event)
3246 3247
{
	struct stat_round_event *round = &event->stat_round;
3248
	struct evsel *counter;
3249

3250
	evlist__for_each_entry(session->evlist, counter) {
3251 3252 3253 3254 3255 3256 3257 3258
		perf_stat_process_counter(&stat_config, counter);
		process_stat(counter, round->time);
	}

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

3259 3260
static int process_stat_config_event(struct perf_session *session __maybe_unused,
				     union perf_event *event)
3261 3262 3263 3264 3265
{
	perf_event__read_stat_config(&stat_config, &event->stat_config);
	return 0;
}

3266 3267
static int set_maps(struct perf_script *script)
{
3268
	struct evlist *evlist = script->session->evlist;
3269 3270 3271 3272 3273 3274 3275

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

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

3276
	perf_evlist__set_maps(&evlist->core, script->cpus, script->threads);
3277 3278 3279 3280 3281 3282 3283 3284 3285

	if (perf_evlist__alloc_stats(evlist, true))
		return -ENOMEM;

	script->allocated = true;
	return 0;
}

static
3286 3287
int process_thread_map_event(struct perf_session *session,
			     union perf_event *event)
3288
{
3289
	struct perf_tool *tool = session->tool;
3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304
	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
3305 3306
int process_cpu_map_event(struct perf_session *session,
			  union perf_event *event)
3307
{
3308
	struct perf_tool *tool = session->tool;
3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322
	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);
}

3323 3324
static int process_feature_event(struct perf_session *session,
				 union perf_event *event)
3325 3326
{
	if (event->feat.feat_id < HEADER_LAST_FEATURE)
3327
		return perf_event__process_feature(session, event);
3328 3329 3330
	return 0;
}

3331
#ifdef HAVE_AUXTRACE_SUPPORT
3332 3333
static int perf_script__process_auxtrace_info(struct perf_session *session,
					      union perf_event *event)
3334
{
3335 3336 3337
	struct perf_tool *tool = session->tool;

	int ret = perf_event__process_auxtrace_info(session, event);
3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350

	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

3351 3352 3353 3354 3355 3356
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);
3357
	symbol_conf.nanosecs = true;
3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368
	return 0;
}

static int parse_xed(const struct option *opt __maybe_unused,
		     const char *str __maybe_unused,
		     int unset __maybe_unused)
{
	force_pager("xed -F insn: -A -64 | less");
	return 0;
}

3369 3370 3371 3372 3373 3374
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);
3375
	symbol_conf.nanosecs = true;
3376
	symbol_conf.pad_output_len_dso = 50;
3377 3378 3379 3380 3381 3382 3383 3384 3385
	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);
3386
	symbol_conf.nanosecs = true;
3387 3388 3389
	return 0;
}

3390
int cmd_script(int argc, const char **argv)
3391 3392
{
	bool show_full_info = false;
3393 3394
	bool header = false;
	bool header_only = false;
3395
	bool script_started = false;
3396 3397 3398
	char *rec_script_path = NULL;
	char *rep_script_path = NULL;
	struct perf_session *session;
3399 3400 3401 3402
	struct itrace_synth_opts itrace_synth_opts = {
		.set = false,
		.default_no_sample = true,
	};
3403
	struct utsname uts;
3404 3405
	char *script_path = NULL;
	const char **__argv;
3406
	int i, j, err = 0;
3407 3408 3409 3410 3411 3412
	struct perf_script script = {
		.tool = {
			.sample		 = process_sample_event,
			.mmap		 = perf_event__process_mmap,
			.mmap2		 = perf_event__process_mmap2,
			.comm		 = perf_event__process_comm,
3413
			.namespaces	 = perf_event__process_namespaces,
3414 3415
			.exit		 = perf_event__process_exit,
			.fork		 = perf_event__process_fork,
3416
			.attr		 = process_attr,
3417
			.event_update   = perf_event__process_event_update,
3418
			.tracing_data	 = perf_event__process_tracing_data,
3419
			.feature	 = process_feature_event,
3420
			.build_id	 = perf_event__process_build_id,
3421
			.id_index	 = perf_event__process_id_index,
3422
			.auxtrace_info	 = perf_script__process_auxtrace_info,
3423 3424
			.auxtrace	 = perf_event__process_auxtrace,
			.auxtrace_error	 = perf_event__process_auxtrace_error,
3425 3426
			.stat		 = perf_event__process_stat_event,
			.stat_round	 = process_stat_round_event,
3427
			.stat_config	 = process_stat_config_event,
3428 3429
			.thread_map	 = process_thread_map_event,
			.cpu_map	 = process_cpu_map_event,
3430
			.ordered_events	 = true,
3431 3432 3433
			.ordering_requires_timestamps = true,
		},
	};
3434
	struct perf_data data = {
3435 3436
		.mode = PERF_DATA_MODE_READ,
	};
3437
	const struct option options[] = {
F
Frederic Weisbecker 已提交
3438 3439
	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
		    "dump raw trace in ASCII"),
3440
	OPT_INCR('v', "verbose", &verbose,
3441
		 "be more verbose (show symbol address, etc)"),
3442
	OPT_BOOLEAN('L', "Latency", &latency_format,
3443
		    "show latency attributes (irqs/preemption disabled, etc)"),
3444 3445
	OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
			   list_available_scripts),
T
Tom Zanussi 已提交
3446 3447 3448 3449
	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",
3450
		   "generate perf-script.xx script in specified language"),
3451
	OPT_STRING('i', "input", &input_name, "file", "input file name"),
3452 3453
	OPT_BOOLEAN('d', "debug-mode", &debug_mode,
		   "do various checks like samples ordering and lost events"),
3454 3455
	OPT_BOOLEAN(0, "header", &header, "Show data header."),
	OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),
3456 3457 3458 3459 3460 3461
	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"),
3462 3463 3464
	OPT_CALLBACK(0, "symfs", NULL, "directory",
		     "Look for files with symbols relative to this directory",
		     symbol__config_symfs),
3465
	OPT_CALLBACK('F', "fields", NULL, "str",
3466
		     "comma separated output fields prepend with 'type:'. "
3467
		     "+field to add and -field to remove."
3468
		     "Valid types: hw,sw,trace,raw,synth. "
3469
		     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
3470 3471
		     "addr,symoff,srcline,period,iregs,uregs,brstack,"
		     "brstacksym,flags,bpf-output,brstackinsn,brstackoff,"
3472
		     "callindent,insn,insnlen,synth,phys_addr,metric,misc,ipc",
3473
		     parse_output_fields),
3474
	OPT_BOOLEAN('a', "all-cpus", &system_wide,
3475
		    "system-wide collection from all CPUs"),
3476 3477
	OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
		   "only consider these symbols"),
3478 3479 3480 3481
	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),
3482 3483 3484 3485
	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),
3486 3487
	OPT_STRING(0, "graph-function", &symbol_conf.graph_function, "symbol[,symbol...]",
			"Only print symbols and callees with --call-trace/--call-ret-trace"),
3488 3489
	OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]",
		   "Stop display of callgraph at these symbols"),
3490
	OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
3491 3492
	OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
		   "only display events for these comms"),
3493 3494 3495 3496
	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"),
3497 3498 3499
	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. "
3500
		     "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
A
Andi Kleen 已提交
3501
	OPT_BOOLEAN(0, "reltime", &reltime, "Show time stamps relative to start"),
3502 3503
	OPT_BOOLEAN('I', "show-info", &show_full_info,
		    "display extended information from perf.data file"),
3504 3505
	OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
		    "Show the path of [kernel.kallsyms]"),
3506 3507
	OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events,
		    "Show the fork/comm/exit events"),
3508 3509
	OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
		    "Show the mmap events"),
3510 3511
	OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
		    "Show context switch events (if recorded)"),
3512 3513
	OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
		    "Show namespace events (if recorded)"),
3514 3515
	OPT_BOOLEAN('\0', "show-lost-events", &script.show_lost_events,
		    "Show lost events (if recorded)"),
3516 3517
	OPT_BOOLEAN('\0', "show-round-events", &script.show_round_events,
		    "Show round events (if recorded)"),
3518 3519
	OPT_BOOLEAN('\0', "show-bpf-events", &script.show_bpf_events,
		    "Show bpf related events (if recorded)"),
3520 3521
	OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
		    "Dump trace output to files named by the monitored events"),
3522
	OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
3523 3524
	OPT_INTEGER(0, "max-blocks", &max_blocks,
		    "Maximum number of code blocks to dump with brstackinsn"),
3525
	OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs,
3526
		    "Use 9 decimal places when displaying time"),
3527
	OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
3528
			    "Instruction Tracing options\n" ITRACE_HELP,
3529
			    itrace_parse_synth_opts),
3530 3531
	OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
			"Show full source file name path for source lines"),
3532 3533 3534 3535
	OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
			"Enable symbol demangling"),
	OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
			"Enable kernel symbol demangling"),
3536 3537
	OPT_STRING(0, "time", &script.time_str, "str",
		   "Time span of interest (start,stop)"),
3538 3539
	OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
		    "Show inline function"),
3540 3541 3542 3543 3544 3545 3546 3547 3548
	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"),
3549
	OPTS_EVSWITCH(&script.evswitch),
3550
	OPT_END()
3551
	};
3552 3553
	const char * const script_subcommands[] = { "record", "report", NULL };
	const char *script_usage[] = {
3554 3555 3556 3557 3558 3559 3560
		"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
	};
3561

3562 3563
	perf_set_singlethreaded();

3564 3565
	setup_scripting();

3566
	argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
3567 3568
			     PARSE_OPT_STOP_AT_NON_OPTION);

3569 3570 3571 3572 3573 3574 3575 3576 3577 3578
	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 已提交
3579 3580
	data.path  = input_name;
	data.force = symbol_conf.force;
3581

3582 3583 3584
	if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
		rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
		if (!rec_script_path)
3585
			return cmd_record(argc, argv);
3586 3587
	}

3588 3589 3590
	if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
		rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
		if (!rep_script_path) {
3591
			fprintf(stderr,
3592
				"Please specify a valid report script"
3593
				"(see 'perf script -l' for listing)\n");
3594 3595 3596 3597
			return -1;
		}
	}

A
Andi Kleen 已提交
3598 3599 3600 3601 3602
	if (script.time_str && reltime) {
		fprintf(stderr, "Don't combine --reltime with --time\n");
		return -1;
	}

3603 3604 3605 3606
	if (itrace_synth_opts.callchain &&
	    itrace_synth_opts.callchain_sz > scripting_max_stack)
		scripting_max_stack = itrace_synth_opts.callchain_sz;

3607
	/* make sure PERF_EXEC_PATH is set for scripts */
3608
	set_argv_exec_path(get_argv_exec_path());
3609

3610
	if (argc && !script_name && !rec_script_path && !rep_script_path) {
3611
		int live_pipe[2];
3612
		int rep_args;
3613 3614
		pid_t pid;

3615 3616 3617 3618
		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) {
3619 3620
			usage_with_options_msg(script_usage, options,
				"Couldn't find script `%s'\n\n See perf"
3621
				" script -l for available scripts.\n", argv[0]);
3622 3623
		}

3624 3625 3626 3627 3628 3629 3630 3631
		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) {
3632 3633
				usage_with_options_msg(script_usage, options,
					"`%s' script requires options."
3634
					"\n\n See perf script -l for available "
3635 3636
					"scripts and options.\n", argv[0]);
			}
3637 3638 3639 3640
		}

		if (pipe(live_pipe) < 0) {
			perror("failed to create pipe");
3641
			return -1;
3642 3643 3644 3645 3646
		}

		pid = fork();
		if (pid < 0) {
			perror("failed to fork");
3647
			return -1;
3648 3649 3650
		}

		if (!pid) {
3651 3652
			j = 0;

3653 3654 3655
			dup2(live_pipe[1], 1);
			close(live_pipe[0]);

3656 3657 3658
			if (is_top_script(argv[0])) {
				system_wide = true;
			} else if (!system_wide) {
3659 3660 3661 3662
				if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
					err = -1;
					goto out;
				}
3663
			}
3664 3665

			__argv = malloc((argc + 6) * sizeof(const char *));
3666 3667 3668 3669 3670
			if (!__argv) {
				pr_err("malloc failed\n");
				err = -ENOMEM;
				goto out;
			}
3671

3672 3673 3674 3675 3676 3677 3678 3679 3680 3681
			__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;
3682 3683

			execvp("/bin/sh", (char **)__argv);
3684
			free(__argv);
3685 3686 3687 3688 3689 3690
			exit(-1);
		}

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

3691
		__argv = malloc((argc + 4) * sizeof(const char *));
3692 3693 3694 3695 3696 3697
		if (!__argv) {
			pr_err("malloc failed\n");
			err = -ENOMEM;
			goto out;
		}

3698 3699 3700 3701 3702 3703 3704 3705
		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;
3706 3707

		execvp("/bin/sh", (char **)__argv);
3708
		free(__argv);
3709 3710 3711
		exit(-1);
	}

3712 3713 3714 3715
	if (rec_script_path)
		script_path = rec_script_path;
	if (rep_script_path)
		script_path = rep_script_path;
3716

3717 3718
	if (script_path) {
		j = 0;
3719

3720 3721
		if (!rec_script_path)
			system_wide = false;
3722 3723 3724 3725 3726 3727
		else if (!system_wide) {
			if (have_cmd(argc - 1, &argv[1]) != 0) {
				err = -1;
				goto out;
			}
		}
3728

3729
		__argv = malloc((argc + 2) * sizeof(const char *));
3730 3731 3732 3733 3734 3735
		if (!__argv) {
			pr_err("malloc failed\n");
			err = -ENOMEM;
			goto out;
		}

3736 3737 3738 3739
		__argv[j++] = "/bin/sh";
		__argv[j++] = script_path;
		if (system_wide)
			__argv[j++] = "-a";
3740
		for (i = 2; i < argc; i++)
3741 3742
			__argv[j++] = argv[i];
		__argv[j++] = NULL;
3743 3744

		execvp("/bin/sh", (char **)__argv);
3745
		free(__argv);
3746 3747
		exit(-1);
	}
T
Tom Zanussi 已提交
3748

3749
	if (!script_name) {
3750
		setup_pager();
3751 3752
		use_browser = 0;
	}
F
Frederic Weisbecker 已提交
3753

3754
	session = perf_session__new(&data, false, &script.tool);
3755
	if (session == NULL)
3756
		return -1;
3757

3758
	if (header || header_only) {
3759
		script.tool.show_feat_hdr = SHOW_FEAT_HEADER;
3760 3761
		perf_session__fprintf_info(session, stdout, show_full_info);
		if (header_only)
3762
			goto out_delete;
3763
	}
3764 3765
	if (show_full_info)
		script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
3766

3767
	if (symbol__init(&session->header.env) < 0)
3768 3769
		goto out_delete;

3770
	uname(&uts);
3771 3772
	if (data.is_pipe ||  /* assume pipe_mode indicates native_arch */
	    !strcmp(uts.machine, session->header.env.arch) ||
3773 3774 3775 3776
	    (!strcmp(uts.machine, "x86_64") &&
	     !strcmp(session->header.env.arch, "i386")))
		native_arch = true;

3777
	script.session = session;
3778
	script__setup_sample_type(&script);
3779

3780 3781
	if ((output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT) ||
	    symbol_conf.graph_function)
3782 3783
		itrace_synth_opts.thread_stack = true;

3784 3785
	session->itrace_synth_opts = &itrace_synth_opts;

3786
	if (cpu_list) {
3787 3788 3789
		err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
		if (err < 0)
			goto out_delete;
3790
		itrace_synth_opts.cpu_bitmap = cpu_bitmap;
3791 3792
	}

3793
	if (!no_callchain)
3794 3795 3796 3797
		symbol_conf.use_callchain = true;
	else
		symbol_conf.use_callchain = false;

3798
	if (session->tevent.pevent &&
3799 3800 3801
	    tep_set_function_resolver(session->tevent.pevent,
				      machine__resolve_kernel_addr,
				      &session->machines.host) < 0) {
3802
		pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
3803 3804
		err = -1;
		goto out_delete;
3805 3806
	}

T
Tom Zanussi 已提交
3807 3808
	if (generate_script_lang) {
		struct stat perf_stat;
3809 3810
		int input;

3811
		if (output_set_by_user()) {
3812 3813
			fprintf(stderr,
				"custom fields not supported for generated scripts");
3814 3815
			err = -EINVAL;
			goto out_delete;
3816
		}
T
Tom Zanussi 已提交
3817

J
Jiri Olsa 已提交
3818
		input = open(data.path, O_RDONLY);	/* input_name */
T
Tom Zanussi 已提交
3819
		if (input < 0) {
3820
			err = -errno;
T
Tom Zanussi 已提交
3821
			perror("failed to open file");
3822
			goto out_delete;
T
Tom Zanussi 已提交
3823 3824 3825 3826 3827
		}

		err = fstat(input, &perf_stat);
		if (err < 0) {
			perror("failed to stat file");
3828
			goto out_delete;
T
Tom Zanussi 已提交
3829 3830 3831 3832
		}

		if (!perf_stat.st_size) {
			fprintf(stderr, "zero-sized file, nothing to do!\n");
3833
			goto out_delete;
T
Tom Zanussi 已提交
3834 3835 3836 3837 3838
		}

		scripting_ops = script_spec__lookup(generate_script_lang);
		if (!scripting_ops) {
			fprintf(stderr, "invalid language specifier");
3839 3840
			err = -ENOENT;
			goto out_delete;
T
Tom Zanussi 已提交
3841 3842
		}

J
Jiri Olsa 已提交
3843
		err = scripting_ops->generate_script(session->tevent.pevent,
3844
						     "perf-script");
3845
		goto out_delete;
T
Tom Zanussi 已提交
3846 3847 3848
	}

	if (script_name) {
3849
		err = scripting_ops->start_script(script_name, argc, argv);
T
Tom Zanussi 已提交
3850
		if (err)
3851
			goto out_delete;
3852
		pr_debug("perf script started with script %s\n\n", script_name);
3853
		script_started = true;
T
Tom Zanussi 已提交
3854 3855
	}

3856 3857 3858

	err = perf_session__check_output_opt(session);
	if (err < 0)
3859
		goto out_delete;
3860

3861 3862 3863 3864 3865 3866
	if (script.time_str) {
		err = perf_time__parse_for_ranges(script.time_str, session,
						  &script.ptime_range,
						  &script.range_size,
						  &script.range_num);
		if (err < 0)
3867
			goto out_delete;
3868 3869 3870 3871

		itrace_synth_opts__set_time_range(&itrace_synth_opts,
						  script.ptime_range,
						  script.range_num);
3872 3873
	}

3874 3875 3876
	err = evswitch__init(&script.evswitch, session->evlist, stderr);
	if (err)
		goto out_delete;
3877

3878
	err = __cmd_script(&script);
T
Tom Zanussi 已提交
3879

3880 3881
	flush_scripting();

3882
out_delete:
3883 3884
	if (script.ptime_range) {
		itrace_synth_opts__clear_time_range(&itrace_synth_opts);
3885
		zfree(&script.ptime_range);
3886
	}
3887

3888
	perf_evlist__free_stats(session->evlist);
3889
	perf_session__delete(session);
3890 3891 3892

	if (script_started)
		cleanup_scripting();
T
Tom Zanussi 已提交
3893 3894
out:
	return err;
F
Frederic Weisbecker 已提交
3895
}