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

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

62
#include <linux/ctype.h>
63

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

83
unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
84

85
enum perf_output_field {
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
	PERF_OUTPUT_COMM            = 1ULL << 0,
	PERF_OUTPUT_TID             = 1ULL << 1,
	PERF_OUTPUT_PID             = 1ULL << 2,
	PERF_OUTPUT_TIME            = 1ULL << 3,
	PERF_OUTPUT_CPU             = 1ULL << 4,
	PERF_OUTPUT_EVNAME          = 1ULL << 5,
	PERF_OUTPUT_TRACE           = 1ULL << 6,
	PERF_OUTPUT_IP              = 1ULL << 7,
	PERF_OUTPUT_SYM             = 1ULL << 8,
	PERF_OUTPUT_DSO             = 1ULL << 9,
	PERF_OUTPUT_ADDR            = 1ULL << 10,
	PERF_OUTPUT_SYMOFFSET       = 1ULL << 11,
	PERF_OUTPUT_SRCLINE         = 1ULL << 12,
	PERF_OUTPUT_PERIOD          = 1ULL << 13,
	PERF_OUTPUT_IREGS	    = 1ULL << 14,
	PERF_OUTPUT_BRSTACK	    = 1ULL << 15,
	PERF_OUTPUT_BRSTACKSYM	    = 1ULL << 16,
	PERF_OUTPUT_DATA_SRC	    = 1ULL << 17,
	PERF_OUTPUT_WEIGHT	    = 1ULL << 18,
	PERF_OUTPUT_BPF_OUTPUT	    = 1ULL << 19,
	PERF_OUTPUT_CALLINDENT	    = 1ULL << 20,
	PERF_OUTPUT_INSN	    = 1ULL << 21,
	PERF_OUTPUT_INSNLEN	    = 1ULL << 22,
	PERF_OUTPUT_BRSTACKINSN	    = 1ULL << 23,
	PERF_OUTPUT_BRSTACKOFF	    = 1ULL << 24,
	PERF_OUTPUT_SYNTH           = 1ULL << 25,
	PERF_OUTPUT_PHYS_ADDR       = 1ULL << 26,
	PERF_OUTPUT_UREGS	    = 1ULL << 27,
	PERF_OUTPUT_METRIC	    = 1ULL << 28,
	PERF_OUTPUT_MISC            = 1ULL << 29,
	PERF_OUTPUT_SRCCODE	    = 1ULL << 30,
	PERF_OUTPUT_IPC             = 1ULL << 31,
118
	PERF_OUTPUT_TOD             = 1ULL << 32,
K
Kan Liang 已提交
119
	PERF_OUTPUT_DATA_PAGE_SIZE  = 1ULL << 33,
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
};

struct perf_script {
	struct perf_tool	tool;
	struct perf_session	*session;
	bool			show_task_events;
	bool			show_mmap_events;
	bool			show_switch_events;
	bool			show_namespace_events;
	bool			show_lost_events;
	bool			show_round_events;
	bool			show_bpf_events;
	bool			show_cgroup_events;
	bool			show_text_poke_events;
	bool			allocated;
	bool			per_event_dump;
	bool			stitch_lbr;
	struct evswitch		evswitch;
	struct perf_cpu_map	*cpus;
	struct perf_thread_map *threads;
	int			name_width;
	const char              *time_str;
	struct perf_time_interval *ptime_range;
	int			range_size;
	int			range_num;
145 146 147 148 149 150 151 152 153 154 155 156 157
};

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

187 188 189 190 191
enum {
	OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,
	OUTPUT_TYPE_MAX
};

192
/* default set to maintain compatibility with current format */
193 194
static struct {
	bool user_set;
195
	bool wildcard_set;
196
	unsigned int print_ip_opts;
197 198
	u64 fields;
	u64 invalid_fields;
199
	u64 user_set_fields;
200
	u64 user_unset_fields;
201
} output[OUTPUT_TYPE_MAX] = {
202 203 204 205 206 207

	[PERF_TYPE_HARDWARE] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
208
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
209 210
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
211

212
		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
213 214 215 216 217 218 219
	},

	[PERF_TYPE_SOFTWARE] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
220
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
221 222 223
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
			      PERF_OUTPUT_BPF_OUTPUT,
224 225 226 227 228 229 230 231 232

		.invalid_fields = PERF_OUTPUT_TRACE,
	},

	[PERF_TYPE_TRACEPOINT] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
				  PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
233
				  PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE
234
	},
235

236 237 238 239 240 241 242 243 244 245 246 247
	[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,
	},

248 249 250 251 252
	[PERF_TYPE_RAW] = {
		.user_set = false,

		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
253
			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
254 255 256
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
			      PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC |
K
Kan Liang 已提交
257 258
			      PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR |
			      PERF_OUTPUT_DATA_PAGE_SIZE,
259

260
		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
261
	},
262 263 264 265 266 267 268

	[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 |
269 270
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
271

272
		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
273
	},
274 275 276 277 278 279 280

	[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 |
281 282
			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
			      PERF_OUTPUT_DSO | PERF_OUTPUT_SYNTH,
283 284 285

		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
	},
286
};
287

288
struct evsel_script {
289 290 291
       char *filename;
       FILE *fp;
       u64  samples;
292 293 294
       /* For metric output */
       u64  val;
       int  gnum;
295 296
};

297
static inline struct evsel_script *evsel_script(struct evsel *evsel)
298
{
299
	return (struct evsel_script *)evsel->priv;
300 301
}

302
static struct evsel_script *perf_evsel_script__new(struct evsel *evsel,
303
							struct perf_data *data)
304
{
305
	struct evsel_script *es = zalloc(sizeof(*es));
306 307

	if (es != NULL) {
308
		if (asprintf(&es->filename, "%s.%s.dump", data->file.path, evsel__name(evsel)) < 0)
309 310 311 312 313 314 315 316 317 318 319 320 321 322
			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;
}

323
static void perf_evsel_script__delete(struct evsel_script *es)
324 325 326 327 328 329 330
{
	zfree(&es->filename);
	fclose(es->fp);
	es->fp = NULL;
	free(es);
}

331
static int perf_evsel_script__fprintf(struct evsel_script *es, FILE *fp)
332 333 334 335 336 337 338 339
{
	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);
}

340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
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;
	}
}

360 361 362
static bool output_set_by_user(void)
{
	int j;
363
	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
364 365 366 367 368
		if (output[j].user_set)
			return true;
	}
	return false;
}
369

370 371 372 373 374 375 376 377 378 379 380 381 382 383
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;
}

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

386 387
static int evsel__do_check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
				 enum perf_output_field field, bool allow_user_set)
388
{
389
	struct perf_event_attr *attr = &evsel->core.attr;
390
	int type = output_type(attr->type);
391 392 393 394 395
	const char *evname;

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

396
	if (output[type].user_set_fields & field) {
397 398
		if (allow_user_set)
			return 0;
399
		evname = evsel__name(evsel);
400 401 402 403 404 405 406 407
		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;
408
	evname = evsel__name(evsel);
409 410 411 412 413 414 415
	pr_debug("Samples for '%s' event do not have %s attribute set. "
		 "Skipping '%s' field.\n",
		 evname, sample_msg, output_field2str(field));

	return 0;
}

416 417
static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
			      enum perf_output_field field)
418
{
419
	return evsel__do_check_stype(evsel, sample_type, sample_msg, field, false);
420 421
}

422
static int evsel__check_attr(struct evsel *evsel, struct perf_session *session)
423
{
424
	struct perf_event_attr *attr = &evsel->core.attr;
425 426
	bool allow_user_set;

427 428 429
	if (perf_header__has_feat(&session->header, HEADER_STAT))
		return 0;

430 431
	allow_user_set = perf_header__has_feat(&session->header,
					       HEADER_AUXTRACE);
432

433
	if (PRINT_FIELD(TRACE) &&
434
	    !perf_session__has_traces(session, "record -R"))
435 436
		return -EINVAL;

437
	if (PRINT_FIELD(IP)) {
438
		if (evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", PERF_OUTPUT_IP))
439 440
			return -EINVAL;
	}
441 442

	if (PRINT_FIELD(ADDR) &&
443
	    evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", PERF_OUTPUT_ADDR, allow_user_set))
444 445
		return -EINVAL;

446
	if (PRINT_FIELD(DATA_SRC) &&
447
	    evsel__check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC", PERF_OUTPUT_DATA_SRC))
448 449 450
		return -EINVAL;

	if (PRINT_FIELD(WEIGHT) &&
451
	    evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT, "WEIGHT", PERF_OUTPUT_WEIGHT))
452 453
		return -EINVAL;

454
	if (PRINT_FIELD(SYM) &&
455
	    !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
456
		pr_err("Display of symbols requested but neither sample IP nor "
457
			   "sample address\navailable. Hence, no addresses to convert "
458
		       "to symbols.\n");
459 460
		return -EINVAL;
	}
461 462 463 464 465
	if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
		pr_err("Display of offsets requested but symbol is not"
		       "selected.\n");
		return -EINVAL;
	}
466
	if (PRINT_FIELD(DSO) &&
467
	    !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
468
		pr_err("Display of DSO requested but no address to convert.\n");
469 470
		return -EINVAL;
	}
A
Andi Kleen 已提交
471
	if ((PRINT_FIELD(SRCLINE) || PRINT_FIELD(SRCCODE)) && !PRINT_FIELD(IP)) {
472 473 474 475
		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;
	}
476
	if (PRINT_FIELD(BRSTACKINSN) && !allow_user_set &&
477
	    !(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY)) {
478 479 480 481
		pr_err("Display of branch stack assembler requested, but non all-branch filter set\n"
		       "Hint: run 'perf record -b ...'\n");
		return -EINVAL;
	}
482
	if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
483
	    evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", PERF_OUTPUT_TID|PERF_OUTPUT_PID))
484 485 486
		return -EINVAL;

	if (PRINT_FIELD(TIME) &&
487
	    evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", PERF_OUTPUT_TIME))
488 489 490
		return -EINVAL;

	if (PRINT_FIELD(CPU) &&
491
	    evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU", PERF_OUTPUT_CPU, allow_user_set))
492
		return -EINVAL;
493

494
	if (PRINT_FIELD(IREGS) &&
495
	    evsel__do_check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", PERF_OUTPUT_IREGS, allow_user_set))
496 497
		return -EINVAL;

A
Andi Kleen 已提交
498
	if (PRINT_FIELD(UREGS) &&
499
	    evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS", PERF_OUTPUT_UREGS))
A
Andi Kleen 已提交
500 501
		return -EINVAL;

502
	if (PRINT_FIELD(PHYS_ADDR) &&
503
	    evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", PERF_OUTPUT_PHYS_ADDR))
504 505
		return -EINVAL;

K
Kan Liang 已提交
506 507 508 509
	if (PRINT_FIELD(DATA_PAGE_SIZE) &&
	    evsel__check_stype(evsel, PERF_SAMPLE_DATA_PAGE_SIZE, "DATA_PAGE_SIZE", PERF_OUTPUT_DATA_PAGE_SIZE))
		return -EINVAL;

510 511 512
	return 0;
}

513 514
static void set_print_ip_opts(struct perf_event_attr *attr)
{
515
	unsigned int type = output_type(attr->type);
516 517 518

	output[type].print_ip_opts = 0;
	if (PRINT_FIELD(IP))
519
		output[type].print_ip_opts |= EVSEL__PRINT_IP;
520 521

	if (PRINT_FIELD(SYM))
522
		output[type].print_ip_opts |= EVSEL__PRINT_SYM;
523 524

	if (PRINT_FIELD(DSO))
525
		output[type].print_ip_opts |= EVSEL__PRINT_DSO;
526 527

	if (PRINT_FIELD(SYMOFFSET))
528
		output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET;
529 530

	if (PRINT_FIELD(SRCLINE))
531
		output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
532 533
}

534 535 536 537 538 539
/*
 * verify all user requested events exist and the samples
 * have the expected data
 */
static int perf_session__check_output_opt(struct perf_session *session)
{
540
	bool tod = false;
541
	unsigned int j;
542
	struct evsel *evsel;
543

544 545
	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
		evsel = perf_session__find_first_evtype(session, attr_type(j));
546 547 548 549 550

		/*
		 * even if fields is set to 0 (ie., show nothing) event must
		 * exist if user explicitly includes it on the command line
		 */
551 552
		if (!evsel && output[j].user_set && !output[j].wildcard_set &&
		    j != OUTPUT_TYPE_SYNTH) {
553
			pr_err("%s events do not exist. "
554
			       "Remove corresponding -F option to proceed.\n",
555 556 557 558 559
			       event_type(j));
			return -1;
		}

		if (evsel && output[j].fields &&
560
			evsel__check_attr(evsel, session))
561
			return -1;
562 563 564 565

		if (evsel == NULL)
			continue;

566
		set_print_ip_opts(&evsel->core.attr);
567
		tod |= output[j].fields & PERF_OUTPUT_TOD;
568 569
	}

570 571
	if (!no_callchain) {
		bool use_callchain = false;
572
		bool not_pipe = false;
573

574
		evlist__for_each_entry(session->evlist, evsel) {
575
			not_pipe = true;
576
			if (evsel__has_callchain(evsel)) {
577 578 579 580
				use_callchain = true;
				break;
			}
		}
581
		if (not_pipe && !use_callchain)
582 583 584
			symbol_conf.use_callchain = false;
	}

585 586 587 588 589 590 591 592
	/*
	 * 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;

593
		evlist__for_each_entry(session->evlist, evsel) {
594
			if (evsel->core.attr.type != j)
595 596
				continue;

597
			if (evsel__has_callchain(evsel)) {
598 599
				output[j].fields |= PERF_OUTPUT_IP;
				output[j].fields |= PERF_OUTPUT_SYM;
600
				output[j].fields |= PERF_OUTPUT_SYMOFFSET;
601
				output[j].fields |= PERF_OUTPUT_DSO;
602
				set_print_ip_opts(&evsel->core.attr);
603 604
				goto out;
			}
605 606 607
		}
	}

608 609 610 611 612
	if (tod && !session->header.env.clock.enabled) {
		pr_err("Can't provide 'tod' time, missing clock data. "
		       "Please record with -k/--clockid option.\n");
		return -1;
	}
613
out:
614 615
	return 0;
}
616

617
static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask,
618
				     FILE *fp)
A
Andi Kleen 已提交
619 620
{
	unsigned i = 0, r;
621
	int printed = 0;
A
Andi Kleen 已提交
622 623

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

626
	printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi);
A
Andi Kleen 已提交
627 628 629

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

	return printed;
A
Andi Kleen 已提交
634 635
}

636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 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 682 683 684 685
#define DEFAULT_TOD_FMT "%F %H:%M:%S"

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

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

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

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

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

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

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

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

	return buf;
}

686 687 688 689 690 691 692 693 694 695 696 697 698 699
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);
}

700 701
static int perf_sample__fprintf_start(struct perf_script *script,
				      struct perf_sample *sample,
702
				      struct thread *thread,
703
				      struct evsel *evsel,
704
				      u32 type, FILE *fp)
705
{
706
	struct perf_event_attr *attr = &evsel->core.attr;
707
	unsigned long secs;
708
	unsigned long long nsecs;
709
	int printed = 0;
710
	char tstr[128];
711 712

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

715
		if (latency_format)
716
			printed += fprintf(fp, "%8.8s ", comm);
717
		else if (PRINT_FIELD(IP) && evsel__has_callchain(evsel) && symbol_conf.use_callchain)
718
			printed += fprintf(fp, "%s ", comm);
719
		else
720
			printed += fprintf(fp, "%16s ", comm);
721
	}
722

723
	if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
724
		printed += fprintf(fp, "%5d/%-5d ", sample->pid, sample->tid);
725
	else if (PRINT_FIELD(PID))
726
		printed += fprintf(fp, "%5d ", sample->pid);
727
	else if (PRINT_FIELD(TID))
728
		printed += fprintf(fp, "%5d ", sample->tid);
729 730 731

	if (PRINT_FIELD(CPU)) {
		if (latency_format)
732
			printed += fprintf(fp, "%3d ", sample->cpu);
733
		else
734
			printed += fprintf(fp, "[%03d] ", sample->cpu);
735
	}
736

737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765
	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:
766
			if (has(SWITCH_OUT)) {
767
				ret += fprintf(fp, "S");
768 769 770
				if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT)
					ret += fprintf(fp, "p");
			}
771 772 773 774 775 776 777 778 779 780
		default:
			break;
		}

		#undef has

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

781 782 783 784 785
	if (PRINT_FIELD(TOD)) {
		tod_scnprintf(script, tstr, sizeof(tstr), sample->time);
		printed += fprintf(fp, "%s ", tstr);
	}

786
	if (PRINT_FIELD(TIME)) {
A
Andi Kleen 已提交
787 788 789 790 791
		u64 t = sample->time;
		if (reltime) {
			if (!initial_time)
				initial_time = sample->time;
			t = sample->time - initial_time;
792 793 794 795 796 797 798
		} else if (deltatime) {
			if (previous_time)
				t = sample->time - previous_time;
			else {
				t = 0;
			}
			previous_time = sample->time;
A
Andi Kleen 已提交
799 800
		}
		nsecs = t;
801 802
		secs = nsecs / NSEC_PER_SEC;
		nsecs -= secs * NSEC_PER_SEC;
803

804
		if (symbol_conf.nanosecs)
805
			printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs);
806 807
		else {
			char sample_time[32];
A
Andi Kleen 已提交
808
			timestamp__scnprintf_usec(t, sample_time, sizeof(sample_time));
809
			printed += fprintf(fp, "%12s: ", sample_time);
810
		}
811
	}
812 813

	return printed;
814 815
}

816 817 818 819 820 821 822 823 824
static inline char
mispred_str(struct branch_entry *br)
{
	if (!(br->flags.mispred  || br->flags.predicted))
		return '-';

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

825 826 827
static int perf_sample__fprintf_brstack(struct perf_sample *sample,
					struct thread *thread,
					struct perf_event_attr *attr, FILE *fp)
828 829
{
	struct branch_stack *br = sample->branch_stack;
830
	struct branch_entry *entries = perf_sample__branch_entries(sample);
831 832
	struct addr_location alf, alt;
	u64 i, from, to;
833
	int printed = 0;
834 835

	if (!(br && br->nr))
836
		return 0;
837 838

	for (i = 0; i < br->nr; i++) {
839 840
		from = entries[i].from;
		to   = entries[i].to;
841 842 843 844

		if (PRINT_FIELD(DSO)) {
			memset(&alf, 0, sizeof(alf));
			memset(&alt, 0, sizeof(alt));
845 846
			thread__find_map_fb(thread, sample->cpumode, from, &alf);
			thread__find_map_fb(thread, sample->cpumode, to, &alt);
847 848
		}

849
		printed += fprintf(fp, " 0x%"PRIx64, from);
850
		if (PRINT_FIELD(DSO)) {
851 852 853
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alf.map, fp);
			printed += fprintf(fp, ")");
854 855
		}

856
		printed += fprintf(fp, "/0x%"PRIx64, to);
857
		if (PRINT_FIELD(DSO)) {
858 859 860
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alt.map, fp);
			printed += fprintf(fp, ")");
861 862
		}

863
		printed += fprintf(fp, "/%c/%c/%c/%d ",
864 865 866 867
			mispred_str(entries + i),
			entries[i].flags.in_tx ? 'X' : '-',
			entries[i].flags.abort ? 'A' : '-',
			entries[i].flags.cycles);
868
	}
869 870

	return printed;
871 872
}

873 874 875
static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
					   struct thread *thread,
					   struct perf_event_attr *attr, FILE *fp)
876 877
{
	struct branch_stack *br = sample->branch_stack;
878
	struct branch_entry *entries = perf_sample__branch_entries(sample);
879 880
	struct addr_location alf, alt;
	u64 i, from, to;
881
	int printed = 0;
882 883

	if (!(br && br->nr))
884
		return 0;
885 886 887 888 889

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

		memset(&alf, 0, sizeof(alf));
		memset(&alt, 0, sizeof(alt));
890 891
		from = entries[i].from;
		to   = entries[i].to;
892

893 894
		thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
		thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
895

896
		printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
897
		if (PRINT_FIELD(DSO)) {
898 899 900
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alf.map, fp);
			printed += fprintf(fp, ")");
901
		}
902 903
		printed += fprintf(fp, "%c", '/');
		printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp);
904
		if (PRINT_FIELD(DSO)) {
905 906 907
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alt.map, fp);
			printed += fprintf(fp, ")");
908
		}
909
		printed += fprintf(fp, "/%c/%c/%c/%d ",
910 911 912 913
			mispred_str(entries + i),
			entries[i].flags.in_tx ? 'X' : '-',
			entries[i].flags.abort ? 'A' : '-',
			entries[i].flags.cycles);
914
	}
915 916

	return printed;
917 918
}

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

	if (!(br && br->nr))
930
		return 0;
931 932 933 934 935

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

		memset(&alf, 0, sizeof(alf));
		memset(&alt, 0, sizeof(alt));
936 937
		from = entries[i].from;
		to   = entries[i].to;
938

939
		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
940
		    !alf.map->dso->adjust_symbols)
941 942
			from = map__map_ip(alf.map, from);

943
		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
944
		    !alt.map->dso->adjust_symbols)
945 946
			to = map__map_ip(alt.map, to);

947
		printed += fprintf(fp, " 0x%"PRIx64, from);
948
		if (PRINT_FIELD(DSO)) {
949 950 951
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alf.map, fp);
			printed += fprintf(fp, ")");
952
		}
953
		printed += fprintf(fp, "/0x%"PRIx64, to);
954
		if (PRINT_FIELD(DSO)) {
955 956 957
			printed += fprintf(fp, "(");
			printed += map__fprintf_dsoname(alt.map, fp);
			printed += fprintf(fp, ")");
958
		}
959
		printed += fprintf(fp, "/%c/%c/%c/%d ",
960 961 962 963
			mispred_str(entries + i),
			entries[i].flags.in_tx ? 'X' : '-',
			entries[i].flags.abort ? 'A' : '-',
			entries[i].flags.cycles);
964
	}
965 966

	return printed;
967
}
968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
#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)) {
994
		pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end);
995 996 997 998 999 1000
		return -ENXIO;
	}

	memset(&al, 0, sizeof(al));
	if (end - start > MAXBB - MAXINSN) {
		if (last)
1001
			pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end);
1002
		else
1003
			pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start);
1004 1005 1006
		return 0;
	}

1007
	if (!thread__find_map(thread, *cpumode, start, &al) || !al.map->dso) {
1008
		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
1009 1010 1011
		return 0;
	}
	if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) {
1012
		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
		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)
1025
		pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
1026 1027 1028 1029
			start, end);
	return len;
}

1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 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 1065 1066 1067 1068 1069 1070 1071
static int map__fprintf_srccode(struct map *map, u64 addr, FILE *fp, struct srccode_state *state)
{
	char *srcfile;
	int ret = 0;
	unsigned line;
	int len;
	char *srccode;

	if (!map || !map->dso)
		return 0;
	srcfile = get_srcline_split(map->dso,
				    map__rip_2objdump(map, addr),
				    &line);
	if (!srcfile)
		return 0;

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

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

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

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

out_free_line:
	free(srcfile);
	return ret;
}

A
Andi Kleen 已提交
1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087
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;
}

1088 1089
static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
			    struct perf_insn *x, u8 *inbuf, int len,
1090
			    int insn, FILE *fp, int *total_cycles)
1091
{
1092 1093 1094 1095 1096 1097
	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" : "");
1098
	if (en->flags.cycles) {
1099 1100
		*total_cycles += en->flags.cycles;
		printed += fprintf(fp, " %d cycles [%d]", en->flags.cycles, *total_cycles);
1101
		if (insn)
1102
			printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
1103
	}
1104
	return printed + fprintf(fp, "\n");
1105 1106
}

1107 1108 1109
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)
1110 1111
{
	struct addr_location al;
1112
	int off, printed = 0;
1113 1114 1115

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

1116 1117
	thread__find_map(thread, cpumode, addr, &al);

1118
	if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
1119
		return 0;
1120 1121 1122 1123 1124 1125 1126

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

	if (!al.sym)
1127
		return 0;
1128 1129 1130 1131 1132

	if (al.addr < al.sym->end)
		off = al.addr - al.sym->start;
	else
		off = al.addr - al.map->start - al.sym->start;
1133
	printed += fprintf(fp, "\t%s", al.sym->name);
1134
	if (off)
1135 1136
		printed += fprintf(fp, "%+d", off);
	printed += fprintf(fp, ":");
1137
	if (PRINT_FIELD(SRCLINE))
1138 1139
		printed += map__fprintf_srcline(al.map, al.addr, "\t", fp);
	printed += fprintf(fp, "\n");
1140
	*lastsym = al.sym;
1141 1142

	return printed;
1143 1144
}

1145 1146 1147 1148
static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
					    struct thread *thread,
					    struct perf_event_attr *attr,
					    struct machine *machine, FILE *fp)
1149 1150
{
	struct branch_stack *br = sample->branch_stack;
1151
	struct branch_entry *entries = perf_sample__branch_entries(sample);
1152
	u64 start, end;
1153
	int i, insn, len, nr, ilen, printed = 0;
1154 1155 1156 1157
	struct perf_insn x;
	u8 buffer[MAXBB];
	unsigned off;
	struct symbol *lastsym = NULL;
1158
	int total_cycles = 0;
1159 1160

	if (!(br && br->nr))
1161
		return 0;
1162 1163 1164 1165 1166 1167 1168
	nr = br->nr;
	if (max_blocks && nr > max_blocks + 1)
		nr = max_blocks + 1;

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

1169
	printed += fprintf(fp, "%c", '\n');
1170 1171

	/* Handle first from jump, of which we don't know the entry. */
1172 1173
	len = grab_bb(buffer, entries[nr-1].from,
			entries[nr-1].from,
1174 1175
			machine, thread, &x.is64bit, &x.cpumode, false);
	if (len > 0) {
1176
		printed += ip__fprintf_sym(entries[nr - 1].from, thread,
1177
					   x.cpumode, x.cpu, &lastsym, attr, fp);
1178
		printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1],
1179
					    &x, buffer, len, 0, fp, &total_cycles);
A
Andi Kleen 已提交
1180
		if (PRINT_FIELD(SRCCODE))
1181
			printed += print_srccode(thread, x.cpumode, entries[nr - 1].from);
1182 1183 1184 1185
	}

	/* Print all blocks */
	for (i = nr - 2; i >= 0; i--) {
1186
		if (entries[i].from || entries[i].to)
1187
			pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i,
1188 1189 1190 1191
				 entries[i].from,
				 entries[i].to);
		start = entries[i + 1].to;
		end   = entries[i].from;
1192 1193 1194 1195

		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) {
1196
			end = entries[--i].from;
1197 1198 1199 1200 1201 1202 1203
			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;
1204
		for (off = 0; off < (unsigned)len; off += ilen) {
1205 1206
			uint64_t ip = start + off;

1207
			printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
1208
			if (ip == end) {
1209
				printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp,
1210
							    &total_cycles);
A
Andi Kleen 已提交
1211 1212
				if (PRINT_FIELD(SRCCODE))
					printed += print_srccode(thread, x.cpumode, ip);
1213 1214
				break;
			} else {
1215
				ilen = 0;
1216 1217
				printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip,
						   dump_insn(&x, ip, buffer + off, len - off, &ilen));
1218 1219
				if (ilen == 0)
					break;
A
Andi Kleen 已提交
1220 1221
				if (PRINT_FIELD(SRCCODE))
					print_srccode(thread, x.cpumode, ip);
1222 1223 1224
				insn++;
			}
		}
1225
		if (off != end - start)
1226
			printed += fprintf(fp, "\tmismatch of LBR data and executable\n");
1227 1228 1229 1230 1231 1232
	}

	/*
	 * Hit the branch? In this case we are already done, and the target
	 * has not been executed yet.
	 */
1233
	if (entries[0].from == sample->ip)
1234
		goto out;
1235
	if (entries[0].flags.abort)
1236
		goto out;
1237 1238 1239

	/*
	 * Print final block upto sample
1240 1241 1242 1243 1244
	 *
	 * 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.
1245
	 */
1246
	start = entries[0].to;
1247
	end = sample->ip;
1248 1249 1250 1251
	if (end < start) {
		/* Missing jump. Scan 128 bytes for the next branch */
		end = start + 128;
	}
1252
	len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
1253
	printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
1254 1255 1256 1257 1258
	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)
1259 1260
			goto out;
		printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip,
1261
			dump_insn(&x, sample->ip, buffer, len, NULL));
A
Andi Kleen 已提交
1262 1263
		if (PRINT_FIELD(SRCCODE))
			print_srccode(thread, x.cpumode, sample->ip);
1264
		goto out;
1265 1266
	}
	for (off = 0; off <= end - start; off += ilen) {
1267
		ilen = 0;
1268 1269
		printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", start + off,
				   dump_insn(&x, start + off, buffer + off, len - off, &ilen));
1270 1271
		if (ilen == 0)
			break;
1272 1273 1274 1275 1276 1277 1278
		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 已提交
1279 1280
		if (PRINT_FIELD(SRCCODE))
			print_srccode(thread, x.cpumode, start + off);
1281
	}
1282 1283
out:
	return printed;
1284
}
1285

1286 1287 1288
static int perf_sample__fprintf_addr(struct perf_sample *sample,
				     struct thread *thread,
				     struct perf_event_attr *attr, FILE *fp)
1289 1290
{
	struct addr_location al;
1291
	int printed = fprintf(fp, "%16" PRIx64, sample->addr);
1292 1293

	if (!sample_addr_correlates_sym(attr))
1294
		goto out;
1295

1296
	thread__resolve(thread, &al, sample);
1297 1298

	if (PRINT_FIELD(SYM)) {
1299
		printed += fprintf(fp, " ");
1300
		if (PRINT_FIELD(SYMOFFSET))
1301
			printed += symbol__fprintf_symname_offs(al.sym, &al, fp);
1302
		else
1303
			printed += symbol__fprintf_symname(al.sym, fp);
1304 1305 1306
	}

	if (PRINT_FIELD(DSO)) {
1307 1308 1309
		printed += fprintf(fp, " (");
		printed += map__fprintf_dsoname(al.map, fp);
		printed += fprintf(fp, ")");
1310
	}
1311 1312
out:
	return printed;
1313 1314
}

1315
static const char *resolve_branch_sym(struct perf_sample *sample,
1316
				      struct evsel *evsel,
1317 1318 1319 1320 1321
				      struct thread *thread,
				      struct addr_location *al,
				      u64 *ip)
{
	struct addr_location addr_al;
1322
	struct perf_event_attr *attr = &evsel->core.attr;
1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343
	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;
}

1344
static int perf_sample__fprintf_callindent(struct perf_sample *sample,
1345
					   struct evsel *evsel,
1346 1347
					   struct thread *thread,
					   struct addr_location *al, FILE *fp)
1348
{
1349
	struct perf_event_attr *attr = &evsel->core.attr;
1350
	size_t depth = thread_stack__depth(thread, sample->cpu);
1351 1352 1353
	const char *name = NULL;
	static int spacing;
	int len = 0;
1354
	int dlen = 0;
1355 1356 1357 1358 1359 1360 1361 1362 1363
	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;

1364
	name = resolve_branch_sym(sample, evsel, thread, al, &ip);
1365

1366 1367 1368 1369 1370 1371
	if (PRINT_FIELD(DSO) && !(PRINT_FIELD(IP) || PRINT_FIELD(ADDR))) {
		dlen += fprintf(fp, "(");
		dlen += map__fprintf_dsoname(al->map, fp);
		dlen += fprintf(fp, ")\t");
	}

1372
	if (name)
1373
		len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);
1374
	else if (ip)
1375
		len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip);
1376 1377

	if (len < 0)
1378
		return len;
1379 1380 1381 1382 1383 1384 1385 1386 1387

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

1390
	return len + dlen;
1391 1392
}

1393 1394 1395 1396 1397 1398
__weak void arch_fetch_insn(struct perf_sample *sample __maybe_unused,
			    struct thread *thread __maybe_unused,
			    struct machine *machine __maybe_unused)
{
}

1399 1400 1401 1402
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 已提交
1403
{
1404 1405
	int printed = 0;

1406 1407 1408
	if (sample->insn_len == 0 && native_arch)
		arch_fetch_insn(sample, thread, machine);

A
Andi Kleen 已提交
1409
	if (PRINT_FIELD(INSNLEN))
1410
		printed += fprintf(fp, " ilen: %d", sample->insn_len);
1411
	if (PRINT_FIELD(INSN) && sample->insn_len) {
A
Andi Kleen 已提交
1412 1413
		int i;

1414
		printed += fprintf(fp, " insn:");
A
Andi Kleen 已提交
1415
		for (i = 0; i < sample->insn_len; i++)
1416
			printed += fprintf(fp, " %02x", (unsigned char)sample->insn[i]);
A
Andi Kleen 已提交
1417
	}
1418
	if (PRINT_FIELD(BRSTACKINSN))
1419 1420 1421
		printed += perf_sample__fprintf_brstackinsn(sample, thread, attr, machine, fp);

	return printed;
A
Andi Kleen 已提交
1422 1423
}

1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437
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);
}

1438
static int perf_sample__fprintf_bts(struct perf_sample *sample,
1439
				    struct evsel *evsel,
1440 1441 1442
				    struct thread *thread,
				    struct addr_location *al,
				    struct machine *machine, FILE *fp)
1443
{
1444
	struct perf_event_attr *attr = &evsel->core.attr;
1445
	unsigned int type = output_type(attr->type);
1446
	bool print_srcline_last = false;
1447
	int printed = 0;
1448

1449
	if (PRINT_FIELD(CALLINDENT))
1450
		printed += perf_sample__fprintf_callindent(sample, evsel, thread, al, fp);
1451

1452 1453
	/* print branch_from information */
	if (PRINT_FIELD(IP)) {
1454
		unsigned int print_opts = output[type].print_ip_opts;
1455
		struct callchain_cursor *cursor = NULL;
1456

1457
		if (symbol_conf.use_callchain && sample->callchain &&
1458
		    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
1459
					      sample, NULL, NULL, scripting_max_stack) == 0)
1460
			cursor = &callchain_cursor;
1461 1462

		if (cursor == NULL) {
1463
			printed += fprintf(fp, " ");
1464
			if (print_opts & EVSEL__PRINT_SRCLINE) {
1465
				print_srcline_last = true;
1466
				print_opts &= ~EVSEL__PRINT_SRCLINE;
1467
			}
1468
		} else
1469
			printed += fprintf(fp, "\n");
1470

1471 1472
		printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor,
					       symbol_conf.bt_stop_list, fp);
1473 1474 1475
	}

	/* print branch_to information */
1476
	if (PRINT_FIELD(ADDR) ||
1477
	    ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
1478
	     !output[type].user_set)) {
1479 1480
		printed += fprintf(fp, " => ");
		printed += perf_sample__fprintf_addr(sample, thread, attr, fp);
1481
	}
1482

1483 1484
	printed += perf_sample__fprintf_ipc(sample, attr, fp);

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

1488
	printed += perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
A
Andi Kleen 已提交
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498
	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;
1499 1500
}

1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520
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}
};

1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
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;
}

1533
static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
1534 1535 1536
{
	const char *chars = PERF_IP_FLAG_CHARS;
	const int n = strlen(PERF_IP_FLAG_CHARS);
1537 1538
	bool in_tx = flags & PERF_IP_FLAG_IN_TX;
	const char *name = NULL;
1539 1540 1541
	char str[33];
	int i, pos = 0;

1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555
	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)" : "");
1556 1557
	}

1558 1559 1560 1561 1562 1563 1564 1565 1566
	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;
1567

1568
	return fprintf(fp, "  %-19s ", str);
1569 1570
}

1571 1572 1573 1574 1575 1576
struct printer_data {
	int line_no;
	bool hit_nul;
	bool is_printable;
};

1577 1578 1579
static int sample__fprintf_bpf_output(enum binary_printer_ops op,
				      unsigned int val,
				      void *extra, FILE *fp)
1580 1581 1582
{
	unsigned char ch = (unsigned char)val;
	struct printer_data *printer_data = extra;
1583
	int printed = 0;
1584 1585 1586

	switch (op) {
	case BINARY_PRINT_DATA_BEGIN:
1587
		printed += fprintf(fp, "\n");
1588 1589
		break;
	case BINARY_PRINT_LINE_BEGIN:
1590
		printed += fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" :
1591 1592 1593
						        "           ");
		break;
	case BINARY_PRINT_ADDR:
1594
		printed += fprintf(fp, " %04x:", val);
1595 1596
		break;
	case BINARY_PRINT_NUM_DATA:
1597
		printed += fprintf(fp, " %02x", val);
1598 1599
		break;
	case BINARY_PRINT_NUM_PAD:
1600
		printed += fprintf(fp, "   ");
1601 1602
		break;
	case BINARY_PRINT_SEP:
1603
		printed += fprintf(fp, "  ");
1604 1605 1606 1607 1608 1609
		break;
	case BINARY_PRINT_CHAR_DATA:
		if (printer_data->hit_nul && ch)
			printer_data->is_printable = false;

		if (!isprint(ch)) {
1610
			printed += fprintf(fp, "%c", '.');
1611 1612 1613 1614 1615 1616 1617 1618 1619

			if (!printer_data->is_printable)
				break;

			if (ch == '\0')
				printer_data->hit_nul = true;
			else
				printer_data->is_printable = false;
		} else {
1620
			printed += fprintf(fp, "%c", ch);
1621 1622 1623
		}
		break;
	case BINARY_PRINT_CHAR_PAD:
1624
		printed += fprintf(fp, " ");
1625 1626
		break;
	case BINARY_PRINT_LINE_END:
1627
		printed += fprintf(fp, "\n");
1628 1629 1630 1631 1632 1633
		printer_data->line_no++;
		break;
	case BINARY_PRINT_DATA_END:
	default:
		break;
	}
1634 1635

	return printed;
1636 1637
}

1638
static int perf_sample__fprintf_bpf_output(struct perf_sample *sample, FILE *fp)
1639 1640 1641
{
	unsigned int nr_bytes = sample->raw_size;
	struct printer_data printer_data = {0, false, true};
1642 1643
	int printed = binary__fprintf(sample->raw_data, nr_bytes, 8,
				      sample__fprintf_bpf_output, &printer_data, fp);
1644 1645

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

	return printed;
1649 1650
}

1651
static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp)
1652 1653
{
	if (len > 0 && len < spacing)
1654 1655 1656
		return fprintf(fp, "%*s", spacing - len, "");

	return 0;
1657 1658
}

1659
static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)
1660
{
1661
	return perf_sample__fprintf_spacing(len, 34, fp);
1662 1663
}

1664
static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp)
1665 1666 1667 1668 1669
{
	struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
	int len;

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

1672
	len = fprintf(fp, " IP: %u payload: %#" PRIx64 " ",
1673
		     data->ip, le64_to_cpu(data->payload));
1674
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1675 1676
}

1677
static int perf_sample__fprintf_synth_mwait(struct perf_sample *sample, FILE *fp)
1678 1679 1680 1681 1682
{
	struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
	int len;

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

1685 1686 1687
	len = fprintf(fp, " hints: %#x extensions: %#x ",
		      data->hints, data->extensions);
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1688 1689
}

1690
static int perf_sample__fprintf_synth_pwre(struct perf_sample *sample, FILE *fp)
1691 1692 1693 1694 1695
{
	struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
	int len;

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

1698 1699 1700
	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);
1701 1702
}

1703
static int perf_sample__fprintf_synth_exstop(struct perf_sample *sample, FILE *fp)
1704 1705 1706 1707 1708
{
	struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
	int len;

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

1711 1712
	len = fprintf(fp, " IP: %u ", data->ip);
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1713 1714
}

1715
static int perf_sample__fprintf_synth_pwrx(struct perf_sample *sample, FILE *fp)
1716 1717 1718 1719 1720
{
	struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
	int len;

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

1723
	len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ",
1724 1725
		     data->deepest_cstate, data->last_cstate,
		     data->wake_reason);
1726
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1727 1728
}

1729
static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp)
1730 1731 1732 1733 1734 1735
{
	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))
1736
		return 0;
1737 1738

	freq = (le32_to_cpu(data->freq) + 500) / 1000;
1739
	len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
1740 1741
	if (data->max_nonturbo) {
		percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
1742
		len += fprintf(fp, "(%3u%%) ", percent);
1743
	}
1744
	return len + perf_sample__fprintf_pt_spacing(len, fp);
1745 1746
}

1747
static int perf_sample__fprintf_synth(struct perf_sample *sample,
1748
				      struct evsel *evsel, FILE *fp)
1749
{
1750
	switch (evsel->core.attr.config) {
1751
	case PERF_SYNTH_INTEL_PTWRITE:
1752
		return perf_sample__fprintf_synth_ptwrite(sample, fp);
1753
	case PERF_SYNTH_INTEL_MWAIT:
1754
		return perf_sample__fprintf_synth_mwait(sample, fp);
1755
	case PERF_SYNTH_INTEL_PWRE:
1756
		return perf_sample__fprintf_synth_pwre(sample, fp);
1757
	case PERF_SYNTH_INTEL_EXSTOP:
1758
		return perf_sample__fprintf_synth_exstop(sample, fp);
1759
	case PERF_SYNTH_INTEL_PWRX:
1760
		return perf_sample__fprintf_synth_pwrx(sample, fp);
1761
	case PERF_SYNTH_INTEL_CBR:
1762
		return perf_sample__fprintf_synth_cbr(sample, fp);
1763 1764 1765
	default:
		break;
	}
1766 1767

	return 0;
1768 1769
}

1770
static int evlist__max_name_len(struct evlist *evlist)
1771
{
1772
	struct evsel *evsel;
1773 1774
	int max = 0;

1775
	evlist__for_each_entry(evlist, evsel) {
1776
		int len = strlen(evsel__name(evsel));
1777 1778 1779 1780 1781 1782 1783

		max = MAX(len, max);
	}

	return max;
}

1784
static int data_src__fprintf(u64 data_src, FILE *fp)
J
Jiri Olsa 已提交
1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797
{
	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;

1798
	return fprintf(fp, "%-*s", maxlen, out);
J
Jiri Olsa 已提交
1799 1800
}

1801 1802 1803
struct metric_ctx {
	struct perf_sample	*sample;
	struct thread		*thread;
1804
	struct evsel	*evsel;
1805 1806 1807
	FILE 			*fp;
};

1808 1809
static void script_print_metric(struct perf_stat_config *config __maybe_unused,
				void *ctx, const char *color,
1810 1811 1812 1813 1814 1815 1816
			        const char *fmt,
			        const char *unit, double val)
{
	struct metric_ctx *mctx = ctx;

	if (!fmt)
		return;
1817
	perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
1818
				   PERF_RECORD_SAMPLE, mctx->fp);
1819 1820 1821 1822 1823 1824 1825 1826
	fputs("\tmetric: ", mctx->fp);
	if (color)
		color_fprintf(mctx->fp, color, fmt, val);
	else
		printf(fmt, val);
	fprintf(mctx->fp, " %s\n", unit);
}

1827 1828
static void script_new_line(struct perf_stat_config *config __maybe_unused,
			    void *ctx)
1829 1830 1831
{
	struct metric_ctx *mctx = ctx;

1832
	perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
1833
				   PERF_RECORD_SAMPLE, mctx->fp);
1834 1835 1836 1837 1838
	fputs("\tmetric: ", mctx->fp);
}

static void perf_sample__fprint_metric(struct perf_script *script,
				       struct thread *thread,
1839
				       struct evsel *evsel,
1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853
				       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,
	};
1854
	struct evsel *ev2;
1855 1856 1857
	u64 val;

	if (!evsel->stats)
1858
		evlist__alloc_stats(script->session->evlist, false);
1859 1860 1861 1862 1863
	if (evsel_script(evsel->leader)->gnum++ == 0)
		perf_stat__reset_shadow_stats();
	val = sample->period * evsel->scale;
	perf_stat__update_shadow_stats(evsel,
				       val,
1864 1865
				       sample->cpu,
				       &rt_stat);
1866
	evsel_script(evsel)->val = val;
1867
	if (evsel_script(evsel->leader)->gnum == evsel->leader->core.nr_members) {
1868
		for_each_group_member (ev2, evsel->leader) {
1869
			perf_stat__print_shadow_stats(&stat_config, ev2,
1870 1871 1872
						      evsel_script(ev2)->val,
						      sample->cpu,
						      &ctx,
J
Jin Yao 已提交
1873 1874
						      NULL,
						      &rt_stat);
1875 1876 1877 1878 1879
		}
		evsel_script(evsel->leader)->gnum = 0;
	}
}

1880
static bool show_event(struct perf_sample *sample,
1881
		       struct evsel *evsel,
1882 1883 1884
		       struct thread *thread,
		       struct addr_location *al)
{
1885
	int depth = thread_stack__depth(thread, sample->cpu);
1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920

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

1921
static void process_event(struct perf_script *script,
1922
			  struct perf_sample *sample, struct evsel *evsel,
1923 1924
			  struct addr_location *al,
			  struct machine *machine)
1925
{
1926
	struct thread *thread = al->thread;
1927
	struct perf_event_attr *attr = &evsel->core.attr;
1928
	unsigned int type = output_type(attr->type);
1929
	struct evsel_script *es = evsel->priv;
1930
	FILE *fp = es->fp;
K
Kan Liang 已提交
1931
	char str[PAGE_SIZE_NAME_LEN];
1932

1933
	if (output[type].fields == 0)
1934 1935
		return;

1936 1937 1938
	if (!show_event(sample, evsel, thread, al))
		return;

1939 1940
	if (evswitch__discard(&script->evswitch, evsel))
		return;
1941

1942 1943
	++es->samples;

1944
	perf_sample__fprintf_start(script, sample, thread, evsel,
1945
				   PERF_RECORD_SAMPLE, fp);
1946

J
Jiri Olsa 已提交
1947
	if (PRINT_FIELD(PERIOD))
1948
		fprintf(fp, "%10" PRIu64 " ", sample->period);
J
Jiri Olsa 已提交
1949

1950
	if (PRINT_FIELD(EVNAME)) {
1951
		const char *evname = evsel__name(evsel);
1952 1953

		if (!script->name_width)
1954
			script->name_width = evlist__max_name_len(script->session->evlist);
1955

1956
		fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]");
1957 1958
	}

1959
	if (print_flags)
1960
		perf_sample__fprintf_flags(sample->flags, fp);
1961

1962
	if (is_bts_event(attr)) {
1963
		perf_sample__fprintf_bts(sample, evsel, thread, al, machine, fp);
1964 1965 1966
		return;
	}

1967
	if (PRINT_FIELD(TRACE) && sample->raw_data) {
1968 1969 1970
		event_format__fprintf(evsel->tp_format, sample->cpu,
				      sample->raw_data, sample->raw_size, fp);
	}
1971 1972

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

1975
	if (PRINT_FIELD(ADDR))
1976
		perf_sample__fprintf_addr(sample, thread, attr, fp);
1977

1978
	if (PRINT_FIELD(DATA_SRC))
1979
		data_src__fprintf(sample->data_src, fp);
1980 1981

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

1984
	if (PRINT_FIELD(IP)) {
1985
		struct callchain_cursor *cursor = NULL;
1986

1987 1988 1989
		if (script->stitch_lbr)
			al->thread->lbr_stitch_enable = true;

1990
		if (symbol_conf.use_callchain && sample->callchain &&
1991
		    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
1992
					      sample, NULL, NULL, scripting_max_stack) == 0)
1993
			cursor = &callchain_cursor;
1994

1995
		fputc(cursor ? '\n' : ' ', fp);
1996 1997
		sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor,
				    symbol_conf.bt_stop_list, fp);
1998 1999
	}

2000
	if (PRINT_FIELD(IREGS))
2001
		perf_sample__fprintf_iregs(sample, attr, fp);
2002

A
Andi Kleen 已提交
2003
	if (PRINT_FIELD(UREGS))
2004
		perf_sample__fprintf_uregs(sample, attr, fp);
A
Andi Kleen 已提交
2005

2006
	if (PRINT_FIELD(BRSTACK))
2007
		perf_sample__fprintf_brstack(sample, thread, attr, fp);
2008
	else if (PRINT_FIELD(BRSTACKSYM))
2009
		perf_sample__fprintf_brstacksym(sample, thread, attr, fp);
2010
	else if (PRINT_FIELD(BRSTACKOFF))
2011
		perf_sample__fprintf_brstackoff(sample, thread, attr, fp);
2012

2013
	if (evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
2014 2015
		perf_sample__fprintf_bpf_output(sample, fp);
	perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
2016 2017

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

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

2023 2024
	perf_sample__fprintf_ipc(sample, attr, fp);

2025
	fprintf(fp, "\n");
2026

A
Andi Kleen 已提交
2027 2028 2029 2030 2031 2032
	if (PRINT_FIELD(SRCCODE)) {
		if (map__fprintf_srccode(al->map, al->addr, stdout,
					 &thread->srccode_state))
			printf("\n");
	}

2033 2034
	if (PRINT_FIELD(METRIC))
		perf_sample__fprint_metric(script, thread, evsel, sample, fp);
2035 2036 2037

	if (verbose)
		fflush(fp);
2038 2039
}

T
Tom Zanussi 已提交
2040 2041
static struct scripting_ops	*scripting_ops;

2042
static void __process_stat(struct evsel *counter, u64 tstamp)
2043
{
2044
	int nthreads = perf_thread_map__nr(counter->core.threads);
2045
	int ncpus = evsel__nr_cpus(counter);
2046 2047 2048
	int cpu, thread;
	static int header_printed;

2049
	if (counter->core.system_wide)
2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064
		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",
2065
				counter->core.cpus->map[cpu],
2066
				perf_thread_map__pid(counter->core.threads, thread),
2067 2068 2069 2070
				counts->val,
				counts->ena,
				counts->run,
				tstamp,
2071
				evsel__name(counter));
2072 2073 2074 2075
		}
	}
}

2076
static void process_stat(struct evsel *counter, u64 tstamp)
2077 2078 2079
{
	if (scripting_ops && scripting_ops->process_stat)
		scripting_ops->process_stat(&stat_config, counter, tstamp);
2080 2081
	else
		__process_stat(counter, tstamp);
2082 2083 2084 2085 2086 2087 2088 2089
}

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

T
Tom Zanussi 已提交
2090 2091
static void setup_scripting(void)
{
2092
	setup_perl_scripting();
2093
	setup_python_scripting();
T
Tom Zanussi 已提交
2094 2095
}

2096 2097
static int flush_scripting(void)
{
2098
	return scripting_ops ? scripting_ops->flush_script() : 0;
2099 2100
}

T
Tom Zanussi 已提交
2101 2102
static int cleanup_scripting(void)
{
2103
	pr_debug("\nperf script stopped\n");
2104

2105
	return scripting_ops ? scripting_ops->stop_script() : 0;
T
Tom Zanussi 已提交
2106 2107
}

2108 2109
static bool filter_cpu(struct perf_sample *sample)
{
2110
	if (cpu_list && sample->cpu != (u32)-1)
2111 2112 2113 2114
		return !test_bit(sample->cpu, cpu_bitmap);
	return false;
}

2115
static int process_sample_event(struct perf_tool *tool,
2116
				union perf_event *event,
2117
				struct perf_sample *sample,
2118
				struct evsel *evsel,
2119
				struct machine *machine)
F
Frederic Weisbecker 已提交
2120
{
2121
	struct perf_script *scr = container_of(tool, struct perf_script, tool);
2122
	struct addr_location al;
F
Frederic Weisbecker 已提交
2123

2124 2125
	if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num,
					  sample->time)) {
2126
		return 0;
2127
	}
2128

2129 2130 2131 2132 2133 2134
	if (debug_mode) {
		if (sample->time < last_timestamp) {
			pr_err("Samples misordered, previous: %" PRIu64
				" this: %" PRIu64 "\n", last_timestamp,
				sample->time);
			nr_unordered++;
2135
		}
2136 2137
		last_timestamp = sample->time;
		return 0;
F
Frederic Weisbecker 已提交
2138
	}
2139

2140
	if (machine__resolve(machine, &al, sample) < 0) {
2141 2142 2143 2144 2145 2146
		pr_err("problem processing %d event, skipping it.\n",
		       event->header.type);
		return -1;
	}

	if (al.filtered)
2147
		goto out_put;
2148

2149
	if (filter_cpu(sample))
2150
		goto out_put;
2151

2152 2153 2154
	if (scripting_ops)
		scripting_ops->process_event(event, sample, evsel, &al);
	else
2155
		process_event(scr, sample, evsel, &al, machine);
2156

2157 2158
out_put:
	addr_location__put(&al);
F
Frederic Weisbecker 已提交
2159 2160 2161
	return 0;
}

2162
static int process_attr(struct perf_tool *tool, union perf_event *event,
2163
			struct evlist **pevlist)
2164 2165
{
	struct perf_script *scr = container_of(tool, struct perf_script, tool);
2166
	struct evlist *evlist;
2167
	struct evsel *evsel, *pos;
2168
	u64 sample_type;
2169
	int err;
2170
	static struct evsel_script *es;
2171 2172 2173 2174 2175 2176

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

	evlist = *pevlist;
2177
	evsel = evlist__last(*pevlist);
2178

2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191
	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;
		}
	}

2192 2193
	if (evsel->core.attr.type >= PERF_TYPE_MAX &&
	    evsel->core.attr.type != PERF_TYPE_SYNTH)
2194 2195
		return 0;

2196
	evlist__for_each_entry(evlist, pos) {
2197
		if (pos->core.attr.type == evsel->core.attr.type && pos != evsel)
2198 2199 2200
			return 0;
	}

2201
	if (evsel->core.attr.sample_type) {
2202
		err = evsel__check_attr(evsel, scr->session);
2203 2204 2205
		if (err)
			return err;
	}
2206

2207 2208 2209 2210
	/*
	 * Check if we need to enable callchains based
	 * on events sample_type.
	 */
2211
	sample_type = evlist__combined_sample_type(evlist);
2212
	callchain_param_setup(sample_type);
2213

2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225
	/* Enable fields for callchain entries */
	if (symbol_conf.use_callchain &&
	    (sample_type & PERF_SAMPLE_CALLCHAIN ||
	     sample_type & PERF_SAMPLE_BRANCH_STACK ||
	     (sample_type & PERF_SAMPLE_REGS_USER &&
	      sample_type & PERF_SAMPLE_STACK_USER))) {
		int type = output_type(evsel->core.attr.type);

		if (!(output[type].user_unset_fields & PERF_OUTPUT_IP))
			output[type].fields |= PERF_OUTPUT_IP;
		if (!(output[type].user_unset_fields & PERF_OUTPUT_SYM))
			output[type].fields |= PERF_OUTPUT_SYM;
2226 2227
	}
	set_print_ip_opts(&evsel->core.attr);
2228
	return 0;
2229 2230
}

2231 2232 2233 2234 2235
static int print_event_with_time(struct perf_tool *tool,
				 union perf_event *event,
				 struct perf_sample *sample,
				 struct machine *machine,
				 pid_t pid, pid_t tid, u64 timestamp)
2236 2237 2238
{
	struct perf_script *script = container_of(tool, struct perf_script, tool);
	struct perf_session *session = script->session;
2239
	struct evsel *evsel = evlist__id2evsel(session->evlist, sample->id);
2240
	struct thread *thread = NULL;
2241

2242 2243 2244 2245 2246
	if (evsel && !evsel->core.attr.sample_id_all) {
		sample->cpu = 0;
		sample->time = timestamp;
		sample->pid = pid;
		sample->tid = tid;
2247 2248
	}

2249 2250
	if (filter_cpu(sample))
		return 0;
2251

2252 2253 2254
	if (tid != -1)
		thread = machine__findnew_thread(machine, pid, tid);

2255
	if (evsel) {
2256
		perf_sample__fprintf_start(script, sample, thread, evsel,
2257
					   event->header.type, stdout);
2258
	}
2259

2260
	perf_event__fprintf(event, machine, stdout);
2261

2262
	thread__put(thread);
2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283

	return 0;
}

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

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

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

2286 2287 2288 2289 2290 2291
static int process_namespaces_event(struct perf_tool *tool,
				    union perf_event *event,
				    struct perf_sample *sample,
				    struct machine *machine)
{
	if (perf_event__process_namespaces(tool, event, sample, machine) < 0)
2292
		return -1;
2293

2294 2295
	return print_event(tool, event, sample, machine, event->namespaces.pid,
			   event->namespaces.tid);
2296 2297
}

2298 2299 2300 2301 2302 2303
static int process_cgroup_event(struct perf_tool *tool,
				union perf_event *event,
				struct perf_sample *sample,
				struct machine *machine)
{
	if (perf_event__process_cgroup(tool, event, sample, machine) < 0)
2304
		return -1;
2305

2306 2307
	return print_event(tool, event, sample, machine, sample->pid,
			    sample->tid);
2308 2309
}

2310 2311 2312 2313 2314 2315 2316 2317
static int process_fork_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
	if (perf_event__process_fork(tool, event, sample, machine) < 0)
		return -1;

2318 2319 2320
	return print_event_with_time(tool, event, sample, machine,
				     event->fork.pid, event->fork.tid,
				     event->fork.time);
2321 2322 2323 2324 2325 2326
}
static int process_exit_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
2327 2328 2329
	/* Print before 'exit' deletes anything */
	if (print_event_with_time(tool, event, sample, machine, event->fork.pid,
				  event->fork.tid, event->fork.time))
2330 2331
		return -1;

2332
	return perf_event__process_exit(tool, event, sample, machine);
2333 2334
}

2335 2336 2337 2338 2339 2340 2341 2342
static int process_mmap_event(struct perf_tool *tool,
			      union perf_event *event,
			      struct perf_sample *sample,
			      struct machine *machine)
{
	if (perf_event__process_mmap(tool, event, sample, machine) < 0)
		return -1;

2343 2344
	return print_event(tool, event, sample, machine, event->mmap.pid,
			   event->mmap.tid);
2345 2346 2347 2348 2349 2350 2351 2352 2353 2354
}

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

2355 2356
	return print_event(tool, event, sample, machine, event->mmap2.pid,
			   event->mmap2.tid);
2357 2358
}

2359 2360 2361 2362 2363 2364 2365 2366 2367 2368
static int process_switch_event(struct perf_tool *tool,
				union perf_event *event,
				struct perf_sample *sample,
				struct machine *machine)
{
	struct perf_script *script = container_of(tool, struct perf_script, tool);

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

2369 2370 2371 2372 2373 2374
	if (scripting_ops && scripting_ops->process_switch)
		scripting_ops->process_switch(event, sample, machine);

	if (!script->show_switch_events)
		return 0;

2375 2376
	return print_event(tool, event, sample, machine, sample->pid,
			   sample->tid);
2377 2378
}

2379 2380 2381 2382 2383 2384
static int
process_lost_event(struct perf_tool *tool,
		   union perf_event *event,
		   struct perf_sample *sample,
		   struct machine *machine)
{
2385 2386
	return print_event(tool, event, sample, machine, sample->pid,
			   sample->tid);
2387 2388
}

2389 2390 2391 2392 2393 2394
static int
process_finished_round_event(struct perf_tool *tool __maybe_unused,
			     union perf_event *event,
			     struct ordered_events *oe __maybe_unused)

{
2395
	perf_event__fprintf(event, NULL, stdout);
2396 2397 2398
	return 0;
}

2399 2400 2401 2402 2403 2404 2405 2406 2407
static int
process_bpf_events(struct perf_tool *tool __maybe_unused,
		   union perf_event *event,
		   struct perf_sample *sample,
		   struct machine *machine)
{
	if (machine__process_ksymbol(machine, event, sample) < 0)
		return -1;

2408 2409
	return print_event(tool, event, sample, machine, sample->pid,
			   sample->tid);
2410 2411
}

2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423
static int process_text_poke_events(struct perf_tool *tool,
				    union perf_event *event,
				    struct perf_sample *sample,
				    struct machine *machine)
{
	if (perf_event__process_text_poke(tool, event, sample, machine) < 0)
		return -1;

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

2424
static void sig_handler(int sig __maybe_unused)
2425 2426 2427 2428
{
	session_done = 1;
}

2429 2430
static void perf_script__fclose_per_event_dump(struct perf_script *script)
{
2431
	struct evlist *evlist = script->session->evlist;
2432
	struct evsel *evsel;
2433 2434 2435 2436

	evlist__for_each_entry(evlist, evsel) {
		if (!evsel->priv)
			break;
2437
		perf_evsel_script__delete(evsel->priv);
2438 2439 2440 2441 2442 2443
		evsel->priv = NULL;
	}
}

static int perf_script__fopen_per_event_dump(struct perf_script *script)
{
2444
	struct evsel *evsel;
2445 2446

	evlist__for_each_entry(script->session->evlist, evsel) {
2447 2448 2449 2450 2451 2452 2453 2454 2455 2456
		/*
		 * 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;

2457
		evsel->priv = perf_evsel_script__new(evsel, script->session->data);
2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470
		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)
{
2471 2472
	struct evsel *evsel;
	static struct evsel_script es_stdout;
2473 2474 2475 2476

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

2477 2478
	es_stdout.fp = stdout;

2479
	evlist__for_each_entry(script->session->evlist, evsel)
2480
		evsel->priv = &es_stdout;
2481 2482 2483 2484

	return 0;
}

2485 2486
static void perf_script__exit_per_event_dump_stats(struct perf_script *script)
{
2487
	struct evsel *evsel;
2488 2489

	evlist__for_each_entry(script->session->evlist, evsel) {
2490
		struct evsel_script *es = evsel->priv;
2491 2492 2493 2494 2495 2496 2497

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

2498
static int __cmd_script(struct perf_script *script)
F
Frederic Weisbecker 已提交
2499
{
2500 2501
	int ret;

2502 2503
	signal(SIGINT, sig_handler);

2504 2505
	perf_stat__init_shadow_stats();

2506 2507 2508 2509 2510 2511
	/* 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;
	}
2512 2513 2514 2515
	if (script->show_mmap_events) {
		script->tool.mmap = process_mmap_event;
		script->tool.mmap2 = process_mmap2_event;
	}
2516
	if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch))
2517
		script->tool.context_switch = process_switch_event;
2518 2519
	if (script->show_namespace_events)
		script->tool.namespaces = process_namespaces_event;
2520 2521
	if (script->show_cgroup_events)
		script->tool.cgroup = process_cgroup_event;
2522 2523
	if (script->show_lost_events)
		script->tool.lost = process_lost_event;
2524 2525 2526 2527
	if (script->show_round_events) {
		script->tool.ordered_events = false;
		script->tool.finished_round = process_finished_round_event;
	}
2528
	if (script->show_bpf_events) {
2529 2530
		script->tool.ksymbol = process_bpf_events;
		script->tool.bpf     = process_bpf_events;
2531
	}
2532 2533 2534 2535
	if (script->show_text_poke_events) {
		script->tool.ksymbol   = process_bpf_events;
		script->tool.text_poke = process_text_poke_events;
	}
2536

2537 2538 2539 2540 2541
	if (perf_script__setup_per_event_dump(script)) {
		pr_err("Couldn't create the per event dump files\n");
		return -1;
	}

2542
	ret = perf_session__process_events(script->session);
2543

2544
	if (script->per_event_dump)
2545
		perf_script__exit_per_event_dump_stats(script);
2546

2547
	if (debug_mode)
2548
		pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
2549 2550

	return ret;
F
Frederic Weisbecker 已提交
2551 2552
}

T
Tom Zanussi 已提交
2553 2554 2555
struct script_spec {
	struct list_head	node;
	struct scripting_ops	*ops;
2556
	char			spec[];
T
Tom Zanussi 已提交
2557 2558
};

2559
static LIST_HEAD(script_specs);
T
Tom Zanussi 已提交
2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596

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;

2597
	s = script_spec__new(spec, ops);
T
Tom Zanussi 已提交
2598 2599
	if (!s)
		return -1;
2600 2601
	else
		script_spec__add(s);
T
Tom Zanussi 已提交
2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620

	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 "
2621
		"perf script -s [spec:]script.[spec]):\n\n");
T
Tom Zanussi 已提交
2622 2623 2624 2625 2626 2627 2628

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

	fprintf(stderr, "\n");
}

2629 2630
static int parse_scriptname(const struct option *opt __maybe_unused,
			    const char *str, int unset __maybe_unused)
T
Tom Zanussi 已提交
2631 2632 2633 2634 2635
{
	char spec[PATH_MAX];
	const char *script, *ext;
	int len;

2636
	if (strcmp(str, "lang") == 0) {
T
Tom Zanussi 已提交
2637
		list_available_languages();
2638
		exit(0);
T
Tom Zanussi 已提交
2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657
	}

	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;
2658
		ext = strrchr(script, '.');
T
Tom Zanussi 已提交
2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674
		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;
}

2675 2676
static int parse_output_fields(const struct option *opt __maybe_unused,
			    const char *arg, int unset __maybe_unused)
2677
{
2678
	char *tok, *strtok_saveptr = NULL;
2679
	int i, imax = ARRAY_SIZE(all_output_options);
2680
	int j;
2681 2682
	int rc = 0;
	char *str = strdup(arg);
2683
	int type = -1;
2684
	enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;
2685 2686 2687 2688

	if (!str)
		return -ENOMEM;

2689 2690 2691
	/* 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.
2692
	 */
2693 2694 2695 2696 2697 2698 2699 2700 2701 2702
	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;
2703 2704
		else if (!strcmp(str, "raw"))
			type = PERF_TYPE_RAW;
2705 2706
		else if (!strcmp(str, "break"))
			type = PERF_TYPE_BREAKPOINT;
2707 2708
		else if (!strcmp(str, "synth"))
			type = OUTPUT_TYPE_SYNTH;
2709 2710
		else {
			fprintf(stderr, "Invalid event type in field string.\n");
2711 2712
			rc = -EINVAL;
			goto out;
2713 2714 2715 2716 2717 2718
		}

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

2719 2720 2721 2722
		/* Don't override defaults for +- */
		if (strchr(tok, '+') || strchr(tok, '-'))
			goto parse;

2723 2724
		output[type].fields = 0;
		output[type].user_set = true;
2725
		output[type].wildcard_set = false;
2726 2727 2728 2729 2730 2731 2732 2733 2734 2735

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

2736 2737 2738 2739
		/* Don't override defaults for +- */
		if (strchr(str, '+') || strchr(str, '-'))
			goto parse;

2740 2741 2742
		if (output_set_by_user())
			pr_warning("Overriding previous field request for all events.\n");

2743
		for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2744 2745
			output[j].fields = 0;
			output[j].user_set = true;
2746
			output[j].wildcard_set = true;
2747
		}
2748 2749
	}

2750
parse:
2751
	for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767
		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;
		}

2768
		for (i = 0; i < imax; ++i) {
2769
			if (strcmp(tok, all_output_options[i].str) == 0)
2770 2771
				break;
		}
2772
		if (i == imax && strcmp(tok, "flags") == 0) {
2773
			print_flags = change == REMOVE ? false : true;
2774 2775
			continue;
		}
2776
		if (i == imax) {
2777
			fprintf(stderr, "Invalid field requested.\n");
2778
			rc = -EINVAL;
2779
			goto out;
2780 2781
		}

2782 2783 2784 2785
		if (type == -1) {
			/* add user option to all events types for
			 * which it is valid
			 */
2786
			for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2787 2788 2789
				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));
2790
				} else {
2791
					if (change == REMOVE) {
2792
						output[j].fields &= ~all_output_options[i].field;
2793
						output[j].user_set_fields &= ~all_output_options[i].field;
2794
						output[j].user_unset_fields |= all_output_options[i].field;
2795
					} else {
2796
						output[j].fields |= all_output_options[i].field;
2797
						output[j].user_set_fields |= all_output_options[i].field;
2798
						output[j].user_unset_fields &= ~all_output_options[i].field;
2799
					}
2800 2801
					output[j].user_set = true;
					output[j].wildcard_set = true;
2802
				}
2803 2804 2805 2806 2807 2808 2809 2810 2811
			}
		} 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;
			}
2812 2813 2814 2815
			if (change == REMOVE)
				output[type].fields &= ~all_output_options[i].field;
			else
				output[type].fields |= all_output_options[i].field;
2816 2817
			output[type].user_set = true;
			output[type].wildcard_set = true;
2818
		}
2819 2820
	}

2821 2822 2823 2824 2825 2826
	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));
		}
	}
2827
	goto out;
2828

2829 2830 2831
out_badmix:
	fprintf(stderr, "Cannot mix +-field with overridden fields\n");
	rc = -EINVAL;
2832
out:
2833 2834 2835 2836
	free(str);
	return rc;
}

2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849
#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)))
2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861


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

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

2862
static LIST_HEAD(script_descs);
2863 2864 2865 2866 2867

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

2868
	if (s != NULL && name)
2869 2870 2871 2872 2873 2874 2875
		s->name = strdup(name);

	return s;
}

static void script_desc__delete(struct script_desc *s)
{
2876 2877 2878
	zfree(&s->name);
	zfree(&s->half_liner);
	zfree(&s->args);
2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905
	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)
2906
		return NULL;
2907 2908 2909 2910 2911 2912

	script_desc__add(s);

	return s;
}

2913
static const char *ends_with(const char *str, const char *suffix)
2914 2915
{
	size_t suffix_len = strlen(suffix);
2916
	const char *p = str;
2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936

	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)) {
2937
		p = skip_spaces(line);
2938 2939 2940 2941 2942 2943 2944 2945
		if (strlen(p) == 0)
			continue;
		if (*p != '#')
			continue;
		p++;
		if (strlen(p) && *p == '!')
			continue;

2946
		p = skip_spaces(p);
2947 2948 2949 2950 2951
		if (strlen(p) && p[strlen(p) - 1] == '\n')
			p[strlen(p) - 1] = '\0';

		if (!strncmp(p, "description:", strlen("description:"))) {
			p += strlen("description:");
2952
			desc->half_liner = strdup(skip_spaces(p));
2953 2954 2955 2956 2957
			continue;
		}

		if (!strncmp(p, "args:", strlen("args:"))) {
			p += strlen("args:");
2958
			desc->args = strdup(skip_spaces(p));
2959 2960 2961 2962 2963 2964 2965 2966 2967
			continue;
		}
	}

	fclose(fp);

	return 0;
}

2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985
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;
}

2986 2987 2988
static int list_available_scripts(const struct option *opt __maybe_unused,
				  const char *s __maybe_unused,
				  int unset __maybe_unused)
2989
{
2990
	struct dirent *script_dirent, *lang_dirent;
2991 2992 2993 2994 2995 2996 2997 2998
	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;

2999
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3000 3001

	scripts_dir = opendir(scripts_path);
3002 3003 3004 3005 3006 3007 3008
	if (!scripts_dir) {
		fprintf(stdout,
			"open(%s) failed.\n"
			"Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",
			scripts_path);
		exit(-1);
	}
3009

3010
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
3011 3012
		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
			  lang_dirent->d_name);
3013 3014 3015 3016
		lang_dir = opendir(lang_path);
		if (!lang_dir)
			continue;

3017 3018
		for_each_script(lang_path, lang_dir, script_dirent) {
			script_root = get_script_root(script_dirent, REPORT_SUFFIX);
3019
			if (script_root) {
3020
				desc = script_desc__findnew(script_root);
3021 3022
				scnprintf(script_path, MAXPATHLEN, "%s/%s",
					  lang_path, script_dirent->d_name);
3023
				read_script_info(desc, script_path);
3024
				free(script_root);
3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039
			}
		}
	}

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

3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053
/*
 * 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;
3054
	struct evsel *pos;
3055 3056 3057
	int match, len;
	FILE *fp;

3058
	scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname);
3059 3060 3061 3062 3063 3064

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

	while (fgets(line, sizeof(line), fp)) {
3065
		p = skip_spaces(line);
3066 3067 3068 3069 3070 3071 3072 3073 3074
		if (*p == '#')
			continue;

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

			p += 2;
3075
			p = skip_spaces(p);
3076 3077 3078 3079 3080 3081 3082
			len = strcspn(p, " \t");
			if (!len)
				break;

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

			match = 0;
3083
			evlist__for_each_entry(session->evlist, pos) {
3084
				if (!strcmp(evsel__name(pos), evname)) {
3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100
					match = 1;
					break;
				}
			}

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

	fclose(fp);
	return 0;
}

3101 3102 3103 3104 3105 3106 3107
/*
 * 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.
 */
3108 3109
int find_scripts(char **scripts_array, char **scripts_path_array, int num,
		 int pathlen)
3110
{
3111
	struct dirent *script_dirent, *lang_dirent;
3112
	char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
3113
	DIR *scripts_dir, *lang_dir;
3114
	struct perf_session *session;
3115
	struct perf_data data = {
J
Jiri Olsa 已提交
3116 3117
		.path = input_name,
		.mode = PERF_DATA_MODE_READ,
3118
	};
3119 3120 3121
	char *temp;
	int i = 0;

3122
	session = perf_session__new(&data, false, NULL);
3123 3124
	if (IS_ERR(session))
		return PTR_ERR(session);
3125

3126
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3127 3128

	scripts_dir = opendir(scripts_path);
3129 3130
	if (!scripts_dir) {
		perf_session__delete(session);
3131
		return -1;
3132
	}
3133

3134
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
3135 3136
		scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
			  lang_dirent->d_name);
3137
#ifndef HAVE_LIBPERL_SUPPORT
3138 3139 3140
		if (strstr(lang_path, "perl"))
			continue;
#endif
3141
#ifndef HAVE_LIBPYTHON_SUPPORT
3142 3143 3144 3145 3146 3147 3148 3149
		if (strstr(lang_path, "python"))
			continue;
#endif

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

3150
		for_each_script(lang_path, lang_dir, script_dirent) {
3151
			/* Skip those real time scripts: xxxtop.p[yl] */
3152
			if (strstr(script_dirent->d_name, "top."))
3153
				continue;
3154 3155 3156 3157
			if (i >= num)
				break;
			snprintf(scripts_path_array[i], pathlen, "%s/%s",
				lang_path,
3158 3159
				script_dirent->d_name);
			temp = strchr(script_dirent->d_name, '.');
3160
			snprintf(scripts_array[i],
3161 3162
				(temp - script_dirent->d_name) + 1,
				"%s", script_dirent->d_name);
3163 3164 3165 3166 3167

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

3168 3169
			i++;
		}
3170
		closedir(lang_dir);
3171 3172
	}

3173 3174
	closedir(scripts_dir);
	perf_session__delete(session);
3175 3176 3177
	return i;
}

3178 3179
static char *get_script_path(const char *script_root, const char *suffix)
{
3180
	struct dirent *script_dirent, *lang_dirent;
3181 3182 3183 3184
	char scripts_path[MAXPATHLEN];
	char script_path[MAXPATHLEN];
	DIR *scripts_dir, *lang_dir;
	char lang_path[MAXPATHLEN];
3185
	char *__script_root;
3186

3187
	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3188 3189 3190 3191 3192

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

3193
	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
3194 3195
		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
			  lang_dirent->d_name);
3196 3197 3198 3199
		lang_dir = opendir(lang_path);
		if (!lang_dir)
			continue;

3200 3201
		for_each_script(lang_path, lang_dir, script_dirent) {
			__script_root = get_script_root(script_dirent, suffix);
3202 3203
			if (__script_root && !strcmp(script_root, __script_root)) {
				free(__script_root);
3204
				closedir(scripts_dir);
3205 3206
				scnprintf(script_path, MAXPATHLEN, "%s/%s",
					  lang_path, script_dirent->d_name);
3207
				closedir(lang_dir);
3208
				return strdup(script_path);
3209 3210 3211
			}
			free(__script_root);
		}
3212
		closedir(lang_dir);
3213
	}
3214
	closedir(scripts_dir);
3215

3216
	return NULL;
3217 3218
}

3219 3220
static bool is_top_script(const char *script_path)
{
3221
	return ends_with(script_path, "top") == NULL ? false : true;
3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246
}

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

3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259
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 已提交
3260

3261 3262 3263 3264 3265
	system_wide = (argc == 0);

	return 0;
}

3266 3267 3268
static void script__setup_sample_type(struct perf_script *script)
{
	struct perf_session *session = script->session;
3269
	u64 sample_type = evlist__combined_sample_type(session->evlist);
3270 3271 3272

	if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
		if ((sample_type & PERF_SAMPLE_REGS_USER) &&
3273
		    (sample_type & PERF_SAMPLE_STACK_USER)) {
3274
			callchain_param.record_mode = CALLCHAIN_DWARF;
3275 3276
			dwarf_callchain_users = true;
		} else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
3277 3278 3279 3280
			callchain_param.record_mode = CALLCHAIN_LBR;
		else
			callchain_param.record_mode = CALLCHAIN_FP;
	}
3281 3282 3283 3284 3285 3286

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

3289 3290
static int process_stat_round_event(struct perf_session *session,
				    union perf_event *event)
3291
{
3292
	struct perf_record_stat_round *round = &event->stat_round;
3293
	struct evsel *counter;
3294

3295
	evlist__for_each_entry(session->evlist, counter) {
3296 3297 3298 3299 3300 3301 3302 3303
		perf_stat_process_counter(&stat_config, counter);
		process_stat(counter, round->time);
	}

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

3304 3305
static int process_stat_config_event(struct perf_session *session __maybe_unused,
				     union perf_event *event)
3306 3307 3308 3309 3310
{
	perf_event__read_stat_config(&stat_config, &event->stat_config);
	return 0;
}

3311 3312
static int set_maps(struct perf_script *script)
{
3313
	struct evlist *evlist = script->session->evlist;
3314 3315 3316 3317 3318 3319 3320

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

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

3321
	perf_evlist__set_maps(&evlist->core, script->cpus, script->threads);
3322

3323
	if (evlist__alloc_stats(evlist, true))
3324 3325 3326 3327 3328 3329 3330
		return -ENOMEM;

	script->allocated = true;
	return 0;
}

static
3331 3332
int process_thread_map_event(struct perf_session *session,
			     union perf_event *event)
3333
{
3334
	struct perf_tool *tool = session->tool;
3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349
	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
3350 3351
int process_cpu_map_event(struct perf_session *session,
			  union perf_event *event)
3352
{
3353
	struct perf_tool *tool = session->tool;
3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367
	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);
}

3368 3369
static int process_feature_event(struct perf_session *session,
				 union perf_event *event)
3370 3371
{
	if (event->feat.feat_id < HEADER_LAST_FEATURE)
3372
		return perf_event__process_feature(session, event);
3373 3374 3375
	return 0;
}

3376
#ifdef HAVE_AUXTRACE_SUPPORT
3377 3378
static int perf_script__process_auxtrace_info(struct perf_session *session,
					      union perf_event *event)
3379
{
3380 3381 3382
	struct perf_tool *tool = session->tool;

	int ret = perf_event__process_auxtrace_info(session, event);
3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395

	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

3396 3397 3398 3399 3400 3401
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);
3402
	symbol_conf.nanosecs = true;
3403 3404 3405 3406 3407 3408 3409
	return 0;
}

static int parse_xed(const struct option *opt __maybe_unused,
		     const char *str __maybe_unused,
		     int unset __maybe_unused)
{
3410 3411 3412 3413
	if (isatty(1))
		force_pager("xed -F insn: -A -64 | less");
	else
		force_pager("xed -F insn: -A -64");
3414 3415 3416
	return 0;
}

3417 3418 3419 3420 3421 3422
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);
3423
	symbol_conf.nanosecs = true;
3424
	symbol_conf.pad_output_len_dso = 50;
3425 3426 3427 3428 3429 3430 3431 3432 3433
	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);
3434
	symbol_conf.nanosecs = true;
3435 3436 3437
	return 0;
}

3438
int cmd_script(int argc, const char **argv)
3439 3440
{
	bool show_full_info = false;
3441 3442
	bool header = false;
	bool header_only = false;
3443
	bool script_started = false;
3444 3445 3446
	char *rec_script_path = NULL;
	char *rep_script_path = NULL;
	struct perf_session *session;
3447 3448 3449 3450
	struct itrace_synth_opts itrace_synth_opts = {
		.set = false,
		.default_no_sample = true,
	};
3451
	struct utsname uts;
3452 3453
	char *script_path = NULL;
	const char **__argv;
3454
	int i, j, err = 0;
3455 3456 3457 3458 3459 3460
	struct perf_script script = {
		.tool = {
			.sample		 = process_sample_event,
			.mmap		 = perf_event__process_mmap,
			.mmap2		 = perf_event__process_mmap2,
			.comm		 = perf_event__process_comm,
3461
			.namespaces	 = perf_event__process_namespaces,
3462
			.cgroup		 = perf_event__process_cgroup,
3463 3464
			.exit		 = perf_event__process_exit,
			.fork		 = perf_event__process_fork,
3465
			.attr		 = process_attr,
3466
			.event_update   = perf_event__process_event_update,
3467
			.tracing_data	 = perf_event__process_tracing_data,
3468
			.feature	 = process_feature_event,
3469
			.build_id	 = perf_event__process_build_id,
3470
			.id_index	 = perf_event__process_id_index,
3471
			.auxtrace_info	 = perf_script__process_auxtrace_info,
3472 3473
			.auxtrace	 = perf_event__process_auxtrace,
			.auxtrace_error	 = perf_event__process_auxtrace_error,
3474 3475
			.stat		 = perf_event__process_stat_event,
			.stat_round	 = process_stat_round_event,
3476
			.stat_config	 = process_stat_config_event,
3477 3478
			.thread_map	 = process_thread_map_event,
			.cpu_map	 = process_cpu_map_event,
3479
			.ordered_events	 = true,
3480 3481 3482
			.ordering_requires_timestamps = true,
		},
	};
3483
	struct perf_data data = {
3484 3485
		.mode = PERF_DATA_MODE_READ,
	};
3486
	const struct option options[] = {
F
Frederic Weisbecker 已提交
3487 3488
	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
		    "dump raw trace in ASCII"),
3489
	OPT_INCR('v', "verbose", &verbose,
3490
		 "be more verbose (show symbol address, etc)"),
3491
	OPT_BOOLEAN('L', "Latency", &latency_format,
3492
		    "show latency attributes (irqs/preemption disabled, etc)"),
3493 3494
	OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
			   list_available_scripts),
T
Tom Zanussi 已提交
3495 3496 3497 3498
	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",
3499
		   "generate perf-script.xx script in specified language"),
3500
	OPT_STRING('i', "input", &input_name, "file", "input file name"),
3501 3502
	OPT_BOOLEAN('d', "debug-mode", &debug_mode,
		   "do various checks like samples ordering and lost events"),
3503 3504
	OPT_BOOLEAN(0, "header", &header, "Show data header."),
	OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),
3505 3506 3507 3508 3509 3510
	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"),
3511 3512 3513
	OPT_CALLBACK(0, "symfs", NULL, "directory",
		     "Look for files with symbols relative to this directory",
		     symbol__config_symfs),
3514
	OPT_CALLBACK('F', "fields", NULL, "str",
3515
		     "comma separated output fields prepend with 'type:'. "
3516
		     "+field to add and -field to remove."
3517
		     "Valid types: hw,sw,trace,raw,synth. "
3518
		     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
3519 3520
		     "addr,symoff,srcline,period,iregs,uregs,brstack,"
		     "brstacksym,flags,bpf-output,brstackinsn,brstackoff,"
K
Kan Liang 已提交
3521 3522
		     "callindent,insn,insnlen,synth,phys_addr,metric,misc,ipc,tod,"
		     "data_page_size",
3523
		     parse_output_fields),
3524
	OPT_BOOLEAN('a', "all-cpus", &system_wide,
3525
		    "system-wide collection from all CPUs"),
3526 3527
	OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
		   "only consider these symbols"),
3528 3529 3530 3531
	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),
3532 3533 3534 3535
	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),
3536 3537
	OPT_STRING(0, "graph-function", &symbol_conf.graph_function, "symbol[,symbol...]",
			"Only print symbols and callees with --call-trace/--call-ret-trace"),
3538 3539
	OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]",
		   "Stop display of callgraph at these symbols"),
3540
	OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
3541 3542
	OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
		   "only display events for these comms"),
3543 3544 3545 3546
	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"),
3547 3548 3549
	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. "
3550
		     "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
A
Andi Kleen 已提交
3551
	OPT_BOOLEAN(0, "reltime", &reltime, "Show time stamps relative to start"),
3552
	OPT_BOOLEAN(0, "deltatime", &deltatime, "Show time stamps relative to previous event"),
3553 3554
	OPT_BOOLEAN('I', "show-info", &show_full_info,
		    "display extended information from perf.data file"),
3555 3556
	OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
		    "Show the path of [kernel.kallsyms]"),
3557 3558
	OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events,
		    "Show the fork/comm/exit events"),
3559 3560
	OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
		    "Show the mmap events"),
3561 3562
	OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
		    "Show context switch events (if recorded)"),
3563 3564
	OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
		    "Show namespace events (if recorded)"),
3565 3566
	OPT_BOOLEAN('\0', "show-cgroup-events", &script.show_cgroup_events,
		    "Show cgroup events (if recorded)"),
3567 3568
	OPT_BOOLEAN('\0', "show-lost-events", &script.show_lost_events,
		    "Show lost events (if recorded)"),
3569 3570
	OPT_BOOLEAN('\0', "show-round-events", &script.show_round_events,
		    "Show round events (if recorded)"),
3571 3572
	OPT_BOOLEAN('\0', "show-bpf-events", &script.show_bpf_events,
		    "Show bpf related events (if recorded)"),
3573 3574
	OPT_BOOLEAN('\0', "show-text-poke-events", &script.show_text_poke_events,
		    "Show text poke related events (if recorded)"),
3575 3576
	OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
		    "Dump trace output to files named by the monitored events"),
3577
	OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
3578 3579
	OPT_INTEGER(0, "max-blocks", &max_blocks,
		    "Maximum number of code blocks to dump with brstackinsn"),
3580
	OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs,
3581
		    "Use 9 decimal places when displaying time"),
3582
	OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
3583
			    "Instruction Tracing options\n" ITRACE_HELP,
3584
			    itrace_parse_synth_opts),
3585 3586
	OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
			"Show full source file name path for source lines"),
3587 3588 3589 3590
	OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
			"Enable symbol demangling"),
	OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
			"Enable kernel symbol demangling"),
3591 3592
	OPT_STRING(0, "time", &script.time_str, "str",
		   "Time span of interest (start,stop)"),
3593 3594
	OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
		    "Show inline function"),
3595 3596 3597 3598 3599 3600 3601 3602 3603
	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"),
3604 3605
	OPT_BOOLEAN('\0', "stitch-lbr", &script.stitch_lbr,
		    "Enable LBR callgraph stitching approach"),
3606
	OPTS_EVSWITCH(&script.evswitch),
3607
	OPT_END()
3608
	};
3609 3610
	const char * const script_subcommands[] = { "record", "report", NULL };
	const char *script_usage[] = {
3611 3612 3613 3614 3615 3616 3617
		"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
	};
3618

3619 3620
	perf_set_singlethreaded();

3621 3622
	setup_scripting();

3623
	argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
3624 3625
			     PARSE_OPT_STOP_AT_NON_OPTION);

3626 3627 3628 3629 3630 3631 3632 3633 3634 3635
	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 已提交
3636 3637
	data.path  = input_name;
	data.force = symbol_conf.force;
3638

3639 3640 3641
	if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
		rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
		if (!rec_script_path)
3642
			return cmd_record(argc, argv);
3643 3644
	}

3645 3646 3647
	if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
		rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
		if (!rep_script_path) {
3648
			fprintf(stderr,
3649
				"Please specify a valid report script"
3650
				"(see 'perf script -l' for listing)\n");
3651 3652 3653 3654
			return -1;
		}
	}

3655 3656 3657 3658 3659 3660 3661
	if (reltime && deltatime) {
		fprintf(stderr,
			"reltime and deltatime - the two don't get along well. "
			"Please limit to --reltime or --deltatime.\n");
		return -1;
	}

3662
	if ((itrace_synth_opts.callchain || itrace_synth_opts.add_callchain) &&
3663 3664 3665
	    itrace_synth_opts.callchain_sz > scripting_max_stack)
		scripting_max_stack = itrace_synth_opts.callchain_sz;

3666
	/* make sure PERF_EXEC_PATH is set for scripts */
3667
	set_argv_exec_path(get_argv_exec_path());
3668

3669
	if (argc && !script_name && !rec_script_path && !rep_script_path) {
3670
		int live_pipe[2];
3671
		int rep_args;
3672 3673
		pid_t pid;

3674 3675 3676 3677
		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) {
3678 3679
			usage_with_options_msg(script_usage, options,
				"Couldn't find script `%s'\n\n See perf"
3680
				" script -l for available scripts.\n", argv[0]);
3681 3682
		}

3683 3684 3685 3686 3687 3688 3689 3690
		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) {
3691 3692
				usage_with_options_msg(script_usage, options,
					"`%s' script requires options."
3693
					"\n\n See perf script -l for available "
3694 3695
					"scripts and options.\n", argv[0]);
			}
3696 3697 3698 3699
		}

		if (pipe(live_pipe) < 0) {
			perror("failed to create pipe");
3700
			return -1;
3701 3702 3703 3704 3705
		}

		pid = fork();
		if (pid < 0) {
			perror("failed to fork");
3706
			return -1;
3707 3708 3709
		}

		if (!pid) {
3710 3711
			j = 0;

3712 3713 3714
			dup2(live_pipe[1], 1);
			close(live_pipe[0]);

3715 3716 3717
			if (is_top_script(argv[0])) {
				system_wide = true;
			} else if (!system_wide) {
3718 3719 3720 3721
				if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
					err = -1;
					goto out;
				}
3722
			}
3723 3724

			__argv = malloc((argc + 6) * sizeof(const char *));
3725 3726 3727 3728 3729
			if (!__argv) {
				pr_err("malloc failed\n");
				err = -ENOMEM;
				goto out;
			}
3730

3731 3732 3733 3734 3735 3736 3737 3738 3739 3740
			__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;
3741 3742

			execvp("/bin/sh", (char **)__argv);
3743
			free(__argv);
3744 3745 3746 3747 3748 3749
			exit(-1);
		}

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

3750
		__argv = malloc((argc + 4) * sizeof(const char *));
3751 3752 3753 3754 3755 3756
		if (!__argv) {
			pr_err("malloc failed\n");
			err = -ENOMEM;
			goto out;
		}

3757 3758 3759 3760 3761 3762 3763 3764
		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;
3765 3766

		execvp("/bin/sh", (char **)__argv);
3767
		free(__argv);
3768 3769 3770
		exit(-1);
	}

3771 3772 3773 3774
	if (rec_script_path)
		script_path = rec_script_path;
	if (rep_script_path)
		script_path = rep_script_path;
3775

3776 3777
	if (script_path) {
		j = 0;
3778

3779 3780
		if (!rec_script_path)
			system_wide = false;
3781 3782 3783 3784 3785 3786
		else if (!system_wide) {
			if (have_cmd(argc - 1, &argv[1]) != 0) {
				err = -1;
				goto out;
			}
		}
3787

3788
		__argv = malloc((argc + 2) * sizeof(const char *));
3789 3790 3791 3792 3793 3794
		if (!__argv) {
			pr_err("malloc failed\n");
			err = -ENOMEM;
			goto out;
		}

3795 3796 3797 3798
		__argv[j++] = "/bin/sh";
		__argv[j++] = script_path;
		if (system_wide)
			__argv[j++] = "-a";
3799
		for (i = 2; i < argc; i++)
3800 3801
			__argv[j++] = argv[i];
		__argv[j++] = NULL;
3802 3803

		execvp("/bin/sh", (char **)__argv);
3804
		free(__argv);
3805 3806
		exit(-1);
	}
T
Tom Zanussi 已提交
3807

3808
	if (!script_name) {
3809
		setup_pager();
3810 3811
		use_browser = 0;
	}
F
Frederic Weisbecker 已提交
3812

3813
	session = perf_session__new(&data, false, &script.tool);
3814 3815
	if (IS_ERR(session))
		return PTR_ERR(session);
3816

3817
	if (header || header_only) {
3818
		script.tool.show_feat_hdr = SHOW_FEAT_HEADER;
3819 3820
		perf_session__fprintf_info(session, stdout, show_full_info);
		if (header_only)
3821
			goto out_delete;
3822
	}
3823 3824
	if (show_full_info)
		script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
3825

3826
	if (symbol__init(&session->header.env) < 0)
3827 3828
		goto out_delete;

3829
	uname(&uts);
3830 3831
	if (data.is_pipe ||  /* assume pipe_mode indicates native_arch */
	    !strcmp(uts.machine, session->header.env.arch) ||
3832 3833 3834 3835
	    (!strcmp(uts.machine, "x86_64") &&
	     !strcmp(session->header.env.arch, "i386")))
		native_arch = true;

3836
	script.session = session;
3837
	script__setup_sample_type(&script);
3838

3839 3840
	if ((output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT) ||
	    symbol_conf.graph_function)
3841 3842
		itrace_synth_opts.thread_stack = true;

3843 3844
	session->itrace_synth_opts = &itrace_synth_opts;

3845
	if (cpu_list) {
3846 3847 3848
		err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
		if (err < 0)
			goto out_delete;
3849
		itrace_synth_opts.cpu_bitmap = cpu_bitmap;
3850 3851
	}

3852
	if (!no_callchain)
3853 3854 3855 3856
		symbol_conf.use_callchain = true;
	else
		symbol_conf.use_callchain = false;

3857
	if (session->tevent.pevent &&
3858 3859 3860
	    tep_set_function_resolver(session->tevent.pevent,
				      machine__resolve_kernel_addr,
				      &session->machines.host) < 0) {
3861
		pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
3862 3863
		err = -1;
		goto out_delete;
3864 3865
	}

T
Tom Zanussi 已提交
3866 3867
	if (generate_script_lang) {
		struct stat perf_stat;
3868 3869
		int input;

3870
		if (output_set_by_user()) {
3871 3872
			fprintf(stderr,
				"custom fields not supported for generated scripts");
3873 3874
			err = -EINVAL;
			goto out_delete;
3875
		}
T
Tom Zanussi 已提交
3876

J
Jiri Olsa 已提交
3877
		input = open(data.path, O_RDONLY);	/* input_name */
T
Tom Zanussi 已提交
3878
		if (input < 0) {
3879
			err = -errno;
T
Tom Zanussi 已提交
3880
			perror("failed to open file");
3881
			goto out_delete;
T
Tom Zanussi 已提交
3882 3883 3884 3885 3886
		}

		err = fstat(input, &perf_stat);
		if (err < 0) {
			perror("failed to stat file");
3887
			goto out_delete;
T
Tom Zanussi 已提交
3888 3889 3890 3891
		}

		if (!perf_stat.st_size) {
			fprintf(stderr, "zero-sized file, nothing to do!\n");
3892
			goto out_delete;
T
Tom Zanussi 已提交
3893 3894 3895 3896 3897
		}

		scripting_ops = script_spec__lookup(generate_script_lang);
		if (!scripting_ops) {
			fprintf(stderr, "invalid language specifier");
3898 3899
			err = -ENOENT;
			goto out_delete;
T
Tom Zanussi 已提交
3900 3901
		}

J
Jiri Olsa 已提交
3902
		err = scripting_ops->generate_script(session->tevent.pevent,
3903
						     "perf-script");
3904
		goto out_delete;
T
Tom Zanussi 已提交
3905 3906 3907
	}

	if (script_name) {
3908
		err = scripting_ops->start_script(script_name, argc, argv);
T
Tom Zanussi 已提交
3909
		if (err)
3910
			goto out_delete;
3911
		pr_debug("perf script started with script %s\n\n", script_name);
3912
		script_started = true;
T
Tom Zanussi 已提交
3913 3914
	}

3915 3916 3917

	err = perf_session__check_output_opt(session);
	if (err < 0)
3918
		goto out_delete;
3919

3920
	if (script.time_str) {
3921
		err = perf_time__parse_for_ranges_reltime(script.time_str, session,
3922 3923
						  &script.ptime_range,
						  &script.range_size,
3924 3925
						  &script.range_num,
						  reltime);
3926
		if (err < 0)
3927
			goto out_delete;
3928 3929 3930 3931

		itrace_synth_opts__set_time_range(&itrace_synth_opts,
						  script.ptime_range,
						  script.range_num);
3932 3933
	}

3934 3935 3936
	err = evswitch__init(&script.evswitch, session->evlist, stderr);
	if (err)
		goto out_delete;
3937

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

3941
	err = __cmd_script(&script);
T
Tom Zanussi 已提交
3942

3943 3944
	flush_scripting();

3945
out_delete:
3946 3947
	if (script.ptime_range) {
		itrace_synth_opts__clear_time_range(&itrace_synth_opts);
3948
		zfree(&script.ptime_range);
3949
	}
3950

3951
	evlist__free_stats(session->evlist);
3952
	perf_session__delete(session);
3953 3954 3955

	if (script_started)
		cleanup_scripting();
T
Tom Zanussi 已提交
3956 3957
out:
	return err;
F
Frederic Weisbecker 已提交
3958
}