brintos

brintos / linux-shallow public Read only

0
0
Text · 120.1 KiB · a644787 Raw
4519 lines · c
1// SPDX-License-Identifier: GPL-2.02#include "builtin.h"3 4#include "util/counts.h"5#include "util/debug.h"6#include "util/dso.h"7#include <subcmd/exec-cmd.h>8#include "util/header.h"9#include <subcmd/parse-options.h>10#include "util/perf_regs.h"11#include "util/session.h"12#include "util/tool.h"13#include "util/map.h"14#include "util/srcline.h"15#include "util/symbol.h"16#include "util/thread.h"17#include "util/trace-event.h"18#include "util/env.h"19#include "util/evlist.h"20#include "util/evsel.h"21#include "util/evsel_fprintf.h"22#include "util/evswitch.h"23#include "util/sort.h"24#include "util/data.h"25#include "util/auxtrace.h"26#include "util/cpumap.h"27#include "util/thread_map.h"28#include "util/stat.h"29#include "util/color.h"30#include "util/string2.h"31#include "util/thread-stack.h"32#include "util/time-utils.h"33#include "util/path.h"34#include "util/event.h"35#include "util/mem-info.h"36#include "ui/ui.h"37#include "print_binary.h"38#include "print_insn.h"39#include "archinsn.h"40#include <linux/bitmap.h>41#include <linux/kernel.h>42#include <linux/stringify.h>43#include <linux/time64.h>44#include <linux/zalloc.h>45#include <sys/utsname.h>46#include "asm/bug.h"47#include "util/mem-events.h"48#include "util/dump-insn.h"49#include <dirent.h>50#include <errno.h>51#include <inttypes.h>52#include <signal.h>53#include <sys/param.h>54#include <sys/types.h>55#include <sys/stat.h>56#include <fcntl.h>57#include <unistd.h>58#include <subcmd/pager.h>59#include <perf/evlist.h>60#include <linux/err.h>61#include "util/dlfilter.h"62#include "util/record.h"63#include "util/util.h"64#include "util/cgroup.h"65#include "util/annotate.h"66#include "perf.h"67 68#include <linux/ctype.h>69#ifdef HAVE_LIBTRACEEVENT70#include <traceevent/event-parse.h>71#endif72 73static char const		*script_name;74static char const		*generate_script_lang;75static bool			reltime;76static bool			deltatime;77static u64			initial_time;78static u64			previous_time;79static bool			debug_mode;80static u64			last_timestamp;81static u64			nr_unordered;82static bool			no_callchain;83static bool			latency_format;84static bool			system_wide;85static bool			print_flags;86static const char		*cpu_list;87static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);88static struct perf_stat_config	stat_config;89static int			max_blocks;90static bool			native_arch;91static struct dlfilter		*dlfilter;92static int			dlargc;93static char			**dlargv;94 95unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;96 97enum perf_output_field {98	PERF_OUTPUT_COMM            = 1ULL << 0,99	PERF_OUTPUT_TID             = 1ULL << 1,100	PERF_OUTPUT_PID             = 1ULL << 2,101	PERF_OUTPUT_TIME            = 1ULL << 3,102	PERF_OUTPUT_CPU             = 1ULL << 4,103	PERF_OUTPUT_EVNAME          = 1ULL << 5,104	PERF_OUTPUT_TRACE           = 1ULL << 6,105	PERF_OUTPUT_IP              = 1ULL << 7,106	PERF_OUTPUT_SYM             = 1ULL << 8,107	PERF_OUTPUT_DSO             = 1ULL << 9,108	PERF_OUTPUT_ADDR            = 1ULL << 10,109	PERF_OUTPUT_SYMOFFSET       = 1ULL << 11,110	PERF_OUTPUT_SRCLINE         = 1ULL << 12,111	PERF_OUTPUT_PERIOD          = 1ULL << 13,112	PERF_OUTPUT_IREGS	    = 1ULL << 14,113	PERF_OUTPUT_BRSTACK	    = 1ULL << 15,114	PERF_OUTPUT_BRSTACKSYM	    = 1ULL << 16,115	PERF_OUTPUT_DATA_SRC	    = 1ULL << 17,116	PERF_OUTPUT_WEIGHT	    = 1ULL << 18,117	PERF_OUTPUT_BPF_OUTPUT	    = 1ULL << 19,118	PERF_OUTPUT_CALLINDENT	    = 1ULL << 20,119	PERF_OUTPUT_INSN	    = 1ULL << 21,120	PERF_OUTPUT_INSNLEN	    = 1ULL << 22,121	PERF_OUTPUT_BRSTACKINSN	    = 1ULL << 23,122	PERF_OUTPUT_BRSTACKOFF	    = 1ULL << 24,123	PERF_OUTPUT_SYNTH           = 1ULL << 25,124	PERF_OUTPUT_PHYS_ADDR       = 1ULL << 26,125	PERF_OUTPUT_UREGS	    = 1ULL << 27,126	PERF_OUTPUT_METRIC	    = 1ULL << 28,127	PERF_OUTPUT_MISC            = 1ULL << 29,128	PERF_OUTPUT_SRCCODE	    = 1ULL << 30,129	PERF_OUTPUT_IPC             = 1ULL << 31,130	PERF_OUTPUT_TOD             = 1ULL << 32,131	PERF_OUTPUT_DATA_PAGE_SIZE  = 1ULL << 33,132	PERF_OUTPUT_CODE_PAGE_SIZE  = 1ULL << 34,133	PERF_OUTPUT_INS_LAT         = 1ULL << 35,134	PERF_OUTPUT_BRSTACKINSNLEN  = 1ULL << 36,135	PERF_OUTPUT_MACHINE_PID     = 1ULL << 37,136	PERF_OUTPUT_VCPU            = 1ULL << 38,137	PERF_OUTPUT_CGROUP          = 1ULL << 39,138	PERF_OUTPUT_RETIRE_LAT      = 1ULL << 40,139	PERF_OUTPUT_DSOFF           = 1ULL << 41,140	PERF_OUTPUT_DISASM          = 1ULL << 42,141	PERF_OUTPUT_BRSTACKDISASM   = 1ULL << 43,142	PERF_OUTPUT_BRCNTR          = 1ULL << 44,143};144 145struct perf_script {146	struct perf_tool	tool;147	struct perf_session	*session;148	bool			show_task_events;149	bool			show_mmap_events;150	bool			show_switch_events;151	bool			show_namespace_events;152	bool			show_lost_events;153	bool			show_round_events;154	bool			show_bpf_events;155	bool			show_cgroup_events;156	bool			show_text_poke_events;157	bool			allocated;158	bool			per_event_dump;159	bool			stitch_lbr;160	struct evswitch		evswitch;161	struct perf_cpu_map	*cpus;162	struct perf_thread_map *threads;163	int			name_width;164	const char              *time_str;165	struct perf_time_interval *ptime_range;166	int			range_size;167	int			range_num;168};169 170struct output_option {171	const char *str;172	enum perf_output_field field;173} all_output_options[] = {174	{.str = "comm",  .field = PERF_OUTPUT_COMM},175	{.str = "tid",   .field = PERF_OUTPUT_TID},176	{.str = "pid",   .field = PERF_OUTPUT_PID},177	{.str = "time",  .field = PERF_OUTPUT_TIME},178	{.str = "cpu",   .field = PERF_OUTPUT_CPU},179	{.str = "event", .field = PERF_OUTPUT_EVNAME},180	{.str = "trace", .field = PERF_OUTPUT_TRACE},181	{.str = "ip",    .field = PERF_OUTPUT_IP},182	{.str = "sym",   .field = PERF_OUTPUT_SYM},183	{.str = "dso",   .field = PERF_OUTPUT_DSO},184	{.str = "dsoff", .field = PERF_OUTPUT_DSOFF},185	{.str = "addr",  .field = PERF_OUTPUT_ADDR},186	{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},187	{.str = "srcline", .field = PERF_OUTPUT_SRCLINE},188	{.str = "period", .field = PERF_OUTPUT_PERIOD},189	{.str = "iregs", .field = PERF_OUTPUT_IREGS},190	{.str = "uregs", .field = PERF_OUTPUT_UREGS},191	{.str = "brstack", .field = PERF_OUTPUT_BRSTACK},192	{.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},193	{.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},194	{.str = "weight",   .field = PERF_OUTPUT_WEIGHT},195	{.str = "bpf-output",   .field = PERF_OUTPUT_BPF_OUTPUT},196	{.str = "callindent", .field = PERF_OUTPUT_CALLINDENT},197	{.str = "insn", .field = PERF_OUTPUT_INSN},198	{.str = "disasm", .field = PERF_OUTPUT_DISASM},199	{.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},200	{.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},201	{.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},202	{.str = "synth", .field = PERF_OUTPUT_SYNTH},203	{.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},204	{.str = "metric", .field = PERF_OUTPUT_METRIC},205	{.str = "misc", .field = PERF_OUTPUT_MISC},206	{.str = "srccode", .field = PERF_OUTPUT_SRCCODE},207	{.str = "ipc", .field = PERF_OUTPUT_IPC},208	{.str = "tod", .field = PERF_OUTPUT_TOD},209	{.str = "data_page_size", .field = PERF_OUTPUT_DATA_PAGE_SIZE},210	{.str = "code_page_size", .field = PERF_OUTPUT_CODE_PAGE_SIZE},211	{.str = "ins_lat", .field = PERF_OUTPUT_INS_LAT},212	{.str = "brstackinsnlen", .field = PERF_OUTPUT_BRSTACKINSNLEN},213	{.str = "machine_pid", .field = PERF_OUTPUT_MACHINE_PID},214	{.str = "vcpu", .field = PERF_OUTPUT_VCPU},215	{.str = "cgroup", .field = PERF_OUTPUT_CGROUP},216	{.str = "retire_lat", .field = PERF_OUTPUT_RETIRE_LAT},217	{.str = "brstackdisasm", .field = PERF_OUTPUT_BRSTACKDISASM},218	{.str = "brcntr", .field = PERF_OUTPUT_BRCNTR},219};220 221enum {222	OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,223	OUTPUT_TYPE_OTHER,224	OUTPUT_TYPE_MAX225};226 227/* default set to maintain compatibility with current format */228static struct {229	bool user_set;230	bool wildcard_set;231	unsigned int print_ip_opts;232	u64 fields;233	u64 invalid_fields;234	u64 user_set_fields;235	u64 user_unset_fields;236} output[OUTPUT_TYPE_MAX] = {237 238	[PERF_TYPE_HARDWARE] = {239		.user_set = false,240 241		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |242			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |243			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |244			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |245			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,246 247		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,248	},249 250	[PERF_TYPE_SOFTWARE] = {251		.user_set = false,252 253		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |254			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |255			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |256			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |257			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |258			      PERF_OUTPUT_BPF_OUTPUT,259 260		.invalid_fields = PERF_OUTPUT_TRACE,261	},262 263	[PERF_TYPE_TRACEPOINT] = {264		.user_set = false,265 266		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |267				  PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |268				  PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE269	},270 271	[PERF_TYPE_HW_CACHE] = {272		.user_set = false,273 274		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |275			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |276			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |277			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |278			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,279 280		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,281	},282 283	[PERF_TYPE_RAW] = {284		.user_set = false,285 286		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |287			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |288			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |289			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |290			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |291			      PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC |292			      PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR |293			      PERF_OUTPUT_DATA_PAGE_SIZE | PERF_OUTPUT_CODE_PAGE_SIZE |294			      PERF_OUTPUT_INS_LAT | PERF_OUTPUT_RETIRE_LAT,295 296		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,297	},298 299	[PERF_TYPE_BREAKPOINT] = {300		.user_set = false,301 302		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |303			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |304			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |305			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |306			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,307 308		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,309	},310 311	[OUTPUT_TYPE_SYNTH] = {312		.user_set = false,313 314		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |315			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |316			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |317			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |318			      PERF_OUTPUT_DSO | PERF_OUTPUT_SYNTH,319 320		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,321	},322 323	[OUTPUT_TYPE_OTHER] = {324		.user_set = false,325 326		.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |327			      PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |328			      PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |329			      PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |330			      PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,331 332		.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,333	},334};335 336struct evsel_script {337       char *filename;338       FILE *fp;339       u64  samples;340       /* For metric output */341       u64  val;342       int  gnum;343};344 345static inline struct evsel_script *evsel_script(struct evsel *evsel)346{347	return (struct evsel_script *)evsel->priv;348}349 350static struct evsel_script *evsel_script__new(struct evsel *evsel, struct perf_data *data)351{352	struct evsel_script *es = zalloc(sizeof(*es));353 354	if (es != NULL) {355		if (asprintf(&es->filename, "%s.%s.dump", data->file.path, evsel__name(evsel)) < 0)356			goto out_free;357		es->fp = fopen(es->filename, "w");358		if (es->fp == NULL)359			goto out_free_filename;360	}361 362	return es;363out_free_filename:364	zfree(&es->filename);365out_free:366	free(es);367	return NULL;368}369 370static void evsel_script__delete(struct evsel_script *es)371{372	zfree(&es->filename);373	fclose(es->fp);374	es->fp = NULL;375	free(es);376}377 378static int evsel_script__fprintf(struct evsel_script *es, FILE *fp)379{380	struct stat st;381 382	fstat(fileno(es->fp), &st);383	return fprintf(fp, "[ perf script: Wrote %.3f MB %s (%" PRIu64 " samples) ]\n",384		       st.st_size / 1024.0 / 1024.0, es->filename, es->samples);385}386 387static inline int output_type(unsigned int type)388{389	switch (type) {390	case PERF_TYPE_SYNTH:391		return OUTPUT_TYPE_SYNTH;392	default:393		if (type < PERF_TYPE_MAX)394			return type;395	}396 397	return OUTPUT_TYPE_OTHER;398}399 400static bool output_set_by_user(void)401{402	int j;403	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {404		if (output[j].user_set)405			return true;406	}407	return false;408}409 410static const char *output_field2str(enum perf_output_field field)411{412	int i, imax = ARRAY_SIZE(all_output_options);413	const char *str = "";414 415	for (i = 0; i < imax; ++i) {416		if (all_output_options[i].field == field) {417			str = all_output_options[i].str;418			break;419		}420	}421	return str;422}423 424#define PRINT_FIELD(x)  (output[output_type(attr->type)].fields & PERF_OUTPUT_##x)425 426static int evsel__do_check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,427				 enum perf_output_field field, bool allow_user_set)428{429	struct perf_event_attr *attr = &evsel->core.attr;430	int type = output_type(attr->type);431	const char *evname;432 433	if (attr->sample_type & sample_type)434		return 0;435 436	if (output[type].user_set_fields & field) {437		if (allow_user_set)438			return 0;439		evname = evsel__name(evsel);440		pr_err("Samples for '%s' event do not have %s attribute set. "441		       "Cannot print '%s' field.\n",442		       evname, sample_msg, output_field2str(field));443		return -1;444	}445 446	/* user did not ask for it explicitly so remove from the default list */447	output[type].fields &= ~field;448	evname = evsel__name(evsel);449	pr_debug("Samples for '%s' event do not have %s attribute set. "450		 "Skipping '%s' field.\n",451		 evname, sample_msg, output_field2str(field));452 453	return 0;454}455 456static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,457			      enum perf_output_field field)458{459	return evsel__do_check_stype(evsel, sample_type, sample_msg, field, false);460}461 462static int evsel__check_attr(struct evsel *evsel, struct perf_session *session)463{464	struct perf_event_attr *attr = &evsel->core.attr;465	bool allow_user_set;466 467	if (evsel__is_dummy_event(evsel))468		return 0;469 470	if (perf_header__has_feat(&session->header, HEADER_STAT))471		return 0;472 473	allow_user_set = perf_header__has_feat(&session->header,474					       HEADER_AUXTRACE);475 476	if (PRINT_FIELD(TRACE) &&477	    !perf_session__has_traces(session, "record -R"))478		return -EINVAL;479 480	if (PRINT_FIELD(IP)) {481		if (evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", PERF_OUTPUT_IP))482			return -EINVAL;483	}484 485	if (PRINT_FIELD(ADDR) &&486	    evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", PERF_OUTPUT_ADDR, allow_user_set))487		return -EINVAL;488 489	if (PRINT_FIELD(DATA_SRC) &&490	    evsel__do_check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC", PERF_OUTPUT_DATA_SRC, allow_user_set))491		return -EINVAL;492 493	if (PRINT_FIELD(WEIGHT) &&494	    evsel__do_check_stype(evsel, PERF_SAMPLE_WEIGHT_TYPE, "WEIGHT", PERF_OUTPUT_WEIGHT, allow_user_set))495		return -EINVAL;496 497	if (PRINT_FIELD(SYM) &&498	    !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {499		pr_err("Display of symbols requested but neither sample IP nor "500			   "sample address\navailable. Hence, no addresses to convert "501		       "to symbols.\n");502		return -EINVAL;503	}504	if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {505		pr_err("Display of offsets requested but symbol is not"506		       "selected.\n");507		return -EINVAL;508	}509	if (PRINT_FIELD(DSO) &&510	    !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {511		pr_err("Display of DSO requested but no address to convert.\n");512		return -EINVAL;513	}514	if ((PRINT_FIELD(SRCLINE) || PRINT_FIELD(SRCCODE)) && !PRINT_FIELD(IP)) {515		pr_err("Display of source line number requested but sample IP is not\n"516		       "selected. Hence, no address to lookup the source line number.\n");517		return -EINVAL;518	}519	if ((PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN) || PRINT_FIELD(BRSTACKDISASM))520	    && !allow_user_set &&521	    !(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY)) {522		pr_err("Display of branch stack assembler requested, but non all-branch filter set\n"523		       "Hint: run 'perf record -b ...'\n");524		return -EINVAL;525	}526	if (PRINT_FIELD(BRCNTR) &&527	    !(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_COUNTERS)) {528		pr_err("Display of branch counter requested but it's not enabled\n"529		       "Hint: run 'perf record -j any,counter ...'\n");530		return -EINVAL;531	}532	if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&533	    evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", PERF_OUTPUT_TID|PERF_OUTPUT_PID))534		return -EINVAL;535 536	if (PRINT_FIELD(TIME) &&537	    evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", PERF_OUTPUT_TIME))538		return -EINVAL;539 540	if (PRINT_FIELD(CPU) &&541	    evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU", PERF_OUTPUT_CPU, allow_user_set))542		return -EINVAL;543 544	if (PRINT_FIELD(IREGS) &&545	    evsel__do_check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", PERF_OUTPUT_IREGS, allow_user_set))546		return -EINVAL;547 548	if (PRINT_FIELD(UREGS) &&549	    evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS", PERF_OUTPUT_UREGS))550		return -EINVAL;551 552	if (PRINT_FIELD(PHYS_ADDR) &&553	    evsel__do_check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", PERF_OUTPUT_PHYS_ADDR, allow_user_set))554		return -EINVAL;555 556	if (PRINT_FIELD(DATA_PAGE_SIZE) &&557	    evsel__check_stype(evsel, PERF_SAMPLE_DATA_PAGE_SIZE, "DATA_PAGE_SIZE", PERF_OUTPUT_DATA_PAGE_SIZE))558		return -EINVAL;559 560	if (PRINT_FIELD(CODE_PAGE_SIZE) &&561	    evsel__check_stype(evsel, PERF_SAMPLE_CODE_PAGE_SIZE, "CODE_PAGE_SIZE", PERF_OUTPUT_CODE_PAGE_SIZE))562		return -EINVAL;563 564	if (PRINT_FIELD(INS_LAT) &&565	    evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT_STRUCT, "WEIGHT_STRUCT", PERF_OUTPUT_INS_LAT))566		return -EINVAL;567 568	if (PRINT_FIELD(CGROUP) &&569	    evsel__check_stype(evsel, PERF_SAMPLE_CGROUP, "CGROUP", PERF_OUTPUT_CGROUP)) {570		pr_err("Hint: run 'perf record --all-cgroups ...'\n");571		return -EINVAL;572	}573 574	if (PRINT_FIELD(RETIRE_LAT) &&575	    evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT_STRUCT, "WEIGHT_STRUCT", PERF_OUTPUT_RETIRE_LAT))576		return -EINVAL;577 578	return 0;579}580 581static void set_print_ip_opts(struct perf_event_attr *attr)582{583	unsigned int type = output_type(attr->type);584 585	output[type].print_ip_opts = 0;586	if (PRINT_FIELD(IP))587		output[type].print_ip_opts |= EVSEL__PRINT_IP;588 589	if (PRINT_FIELD(SYM))590		output[type].print_ip_opts |= EVSEL__PRINT_SYM;591 592	if (PRINT_FIELD(DSO))593		output[type].print_ip_opts |= EVSEL__PRINT_DSO;594 595	if (PRINT_FIELD(DSOFF))596		output[type].print_ip_opts |= EVSEL__PRINT_DSOFF;597 598	if (PRINT_FIELD(SYMOFFSET))599		output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET;600 601	if (PRINT_FIELD(SRCLINE))602		output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;603}604 605static struct evsel *find_first_output_type(struct evlist *evlist,606					    unsigned int type)607{608	struct evsel *evsel;609 610	evlist__for_each_entry(evlist, evsel) {611		if (evsel__is_dummy_event(evsel))612			continue;613		if (output_type(evsel->core.attr.type) == (int)type)614			return evsel;615	}616	return NULL;617}618 619/*620 * verify all user requested events exist and the samples621 * have the expected data622 */623static int perf_session__check_output_opt(struct perf_session *session)624{625	bool tod = false;626	unsigned int j;627	struct evsel *evsel;628 629	for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {630		evsel = find_first_output_type(session->evlist, j);631 632		/*633		 * even if fields is set to 0 (ie., show nothing) event must634		 * exist if user explicitly includes it on the command line635		 */636		if (!evsel && output[j].user_set && !output[j].wildcard_set &&637		    j != OUTPUT_TYPE_SYNTH) {638			pr_err("%s events do not exist. "639			       "Remove corresponding -F option to proceed.\n",640			       event_type(j));641			return -1;642		}643 644		if (evsel && output[j].fields &&645			evsel__check_attr(evsel, session))646			return -1;647 648		if (evsel == NULL)649			continue;650 651		/* 'dsoff' implys 'dso' field */652		if (output[j].fields & PERF_OUTPUT_DSOFF)653			output[j].fields |= PERF_OUTPUT_DSO;654 655		set_print_ip_opts(&evsel->core.attr);656		tod |= output[j].fields & PERF_OUTPUT_TOD;657	}658 659	if (!no_callchain) {660		bool use_callchain = false;661		bool not_pipe = false;662 663		evlist__for_each_entry(session->evlist, evsel) {664			not_pipe = true;665			if (evsel__has_callchain(evsel)) {666				use_callchain = true;667				break;668			}669		}670		if (not_pipe && !use_callchain)671			symbol_conf.use_callchain = false;672	}673 674	/*675	 * set default for tracepoints to print symbols only676	 * if callchains are present677	 */678	if (symbol_conf.use_callchain &&679	    !output[PERF_TYPE_TRACEPOINT].user_set) {680		j = PERF_TYPE_TRACEPOINT;681 682		evlist__for_each_entry(session->evlist, evsel) {683			if (evsel->core.attr.type != j)684				continue;685 686			if (evsel__has_callchain(evsel)) {687				output[j].fields |= PERF_OUTPUT_IP;688				output[j].fields |= PERF_OUTPUT_SYM;689				output[j].fields |= PERF_OUTPUT_SYMOFFSET;690				output[j].fields |= PERF_OUTPUT_DSO;691				set_print_ip_opts(&evsel->core.attr);692				goto out;693			}694		}695	}696 697	if (tod && !session->header.env.clock.enabled) {698		pr_err("Can't provide 'tod' time, missing clock data. "699		       "Please record with -k/--clockid option.\n");700		return -1;701	}702out:703	return 0;704}705 706static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, const char *arch,707				     FILE *fp)708{709	unsigned i = 0, r;710	int printed = 0;711 712	if (!regs || !regs->regs)713		return 0;714 715	printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi);716 717	for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {718		u64 val = regs->regs[i++];719		printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r, arch), val);720	}721 722	return printed;723}724 725#define DEFAULT_TOD_FMT "%F %H:%M:%S"726 727static char*728tod_scnprintf(struct perf_script *script, char *buf, int buflen,729	     u64 timestamp)730{731	u64 tod_ns, clockid_ns;732	struct perf_env *env;733	unsigned long nsec;734	struct tm ltime;735	char date[64];736	time_t sec;737 738	buf[0] = '\0';739	if (buflen < 64 || !script)740		return buf;741 742	env = &script->session->header.env;743	if (!env->clock.enabled) {744		scnprintf(buf, buflen, "disabled");745		return buf;746	}747 748	clockid_ns = env->clock.clockid_ns;749	tod_ns     = env->clock.tod_ns;750 751	if (timestamp > clockid_ns)752		tod_ns += timestamp - clockid_ns;753	else754		tod_ns -= clockid_ns - timestamp;755 756	sec  = (time_t) (tod_ns / NSEC_PER_SEC);757	nsec = tod_ns - sec * NSEC_PER_SEC;758 759	if (localtime_r(&sec, &ltime) == NULL) {760		scnprintf(buf, buflen, "failed");761	} else {762		strftime(date, sizeof(date), DEFAULT_TOD_FMT, &ltime);763 764		if (symbol_conf.nanosecs) {765			snprintf(buf, buflen, "%s.%09lu", date, nsec);766		} else {767			snprintf(buf, buflen, "%s.%06lu",768				 date, nsec / NSEC_PER_USEC);769		}770	}771 772	return buf;773}774 775static int perf_sample__fprintf_iregs(struct perf_sample *sample,776				      struct perf_event_attr *attr, const char *arch, FILE *fp)777{778	return perf_sample__fprintf_regs(&sample->intr_regs,779					 attr->sample_regs_intr, arch, fp);780}781 782static int perf_sample__fprintf_uregs(struct perf_sample *sample,783				      struct perf_event_attr *attr, const char *arch, FILE *fp)784{785	return perf_sample__fprintf_regs(&sample->user_regs,786					 attr->sample_regs_user, arch, fp);787}788 789static int perf_sample__fprintf_start(struct perf_script *script,790				      struct perf_sample *sample,791				      struct thread *thread,792				      struct evsel *evsel,793				      u32 type, FILE *fp)794{795	struct perf_event_attr *attr = &evsel->core.attr;796	unsigned long secs;797	unsigned long long nsecs;798	int printed = 0;799	char tstr[128];800 801	/*802	 * Print the branch counter's abbreviation list,803	 * if the branch counter is available.804	 */805	if (PRINT_FIELD(BRCNTR) && !verbose) {806		char *buf;807 808		if (!annotation_br_cntr_abbr_list(&buf, evsel, true)) {809			printed += fprintf(stdout, "%s", buf);810			free(buf);811		}812	}813 814	if (PRINT_FIELD(MACHINE_PID) && sample->machine_pid)815		printed += fprintf(fp, "VM:%5d ", sample->machine_pid);816 817	/* Print VCPU only for guest events i.e. with machine_pid */818	if (PRINT_FIELD(VCPU) && sample->machine_pid)819		printed += fprintf(fp, "VCPU:%03d ", sample->vcpu);820 821	if (PRINT_FIELD(COMM)) {822		const char *comm = thread ? thread__comm_str(thread) : ":-1";823 824		if (latency_format)825			printed += fprintf(fp, "%8.8s ", comm);826		else if (PRINT_FIELD(IP) && evsel__has_callchain(evsel) && symbol_conf.use_callchain)827			printed += fprintf(fp, "%s ", comm);828		else829			printed += fprintf(fp, "%16s ", comm);830	}831 832	if (PRINT_FIELD(PID) && PRINT_FIELD(TID))833		printed += fprintf(fp, "%7d/%-7d ", sample->pid, sample->tid);834	else if (PRINT_FIELD(PID))835		printed += fprintf(fp, "%7d ", sample->pid);836	else if (PRINT_FIELD(TID))837		printed += fprintf(fp, "%7d ", sample->tid);838 839	if (PRINT_FIELD(CPU)) {840		if (latency_format)841			printed += fprintf(fp, "%3d ", sample->cpu);842		else843			printed += fprintf(fp, "[%03d] ", sample->cpu);844	}845 846	if (PRINT_FIELD(MISC)) {847		int ret = 0;848 849		#define has(m) \850			(sample->misc & PERF_RECORD_MISC_##m) == PERF_RECORD_MISC_##m851 852		if (has(KERNEL))853			ret += fprintf(fp, "K");854		if (has(USER))855			ret += fprintf(fp, "U");856		if (has(HYPERVISOR))857			ret += fprintf(fp, "H");858		if (has(GUEST_KERNEL))859			ret += fprintf(fp, "G");860		if (has(GUEST_USER))861			ret += fprintf(fp, "g");862 863		switch (type) {864		case PERF_RECORD_MMAP:865		case PERF_RECORD_MMAP2:866			if (has(MMAP_DATA))867				ret += fprintf(fp, "M");868			break;869		case PERF_RECORD_COMM:870			if (has(COMM_EXEC))871				ret += fprintf(fp, "E");872			break;873		case PERF_RECORD_SWITCH:874		case PERF_RECORD_SWITCH_CPU_WIDE:875			if (has(SWITCH_OUT)) {876				ret += fprintf(fp, "S");877				if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT)878					ret += fprintf(fp, "p");879			}880		default:881			break;882		}883 884		#undef has885 886		ret += fprintf(fp, "%*s", 6 - ret, " ");887		printed += ret;888	}889 890	if (PRINT_FIELD(TOD)) {891		tod_scnprintf(script, tstr, sizeof(tstr), sample->time);892		printed += fprintf(fp, "%s ", tstr);893	}894 895	if (PRINT_FIELD(TIME)) {896		u64 t = sample->time;897		if (reltime) {898			if (!initial_time)899				initial_time = sample->time;900			t = sample->time - initial_time;901		} else if (deltatime) {902			if (previous_time)903				t = sample->time - previous_time;904			else {905				t = 0;906			}907			previous_time = sample->time;908		}909		nsecs = t;910		secs = nsecs / NSEC_PER_SEC;911		nsecs -= secs * NSEC_PER_SEC;912 913		if (symbol_conf.nanosecs)914			printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs);915		else {916			char sample_time[32];917			timestamp__scnprintf_usec(t, sample_time, sizeof(sample_time));918			printed += fprintf(fp, "%12s: ", sample_time);919		}920	}921 922	return printed;923}924 925static inline char926mispred_str(struct branch_entry *br)927{928	if (!(br->flags.mispred  || br->flags.predicted))929		return '-';930 931	return br->flags.predicted ? 'P' : 'M';932}933 934static int print_bstack_flags(FILE *fp, struct branch_entry *br)935{936	return fprintf(fp, "/%c/%c/%c/%d/%s/%s ",937		       mispred_str(br),938		       br->flags.in_tx ? 'X' : '-',939		       br->flags.abort ? 'A' : '-',940		       br->flags.cycles,941		       get_branch_type(br),942		       br->flags.spec ? branch_spec_desc(br->flags.spec) : "-");943}944 945static int perf_sample__fprintf_brstack(struct perf_sample *sample,946					struct thread *thread,947					struct perf_event_attr *attr, FILE *fp)948{949	struct branch_stack *br = sample->branch_stack;950	struct branch_entry *entries = perf_sample__branch_entries(sample);951	u64 i, from, to;952	int printed = 0;953 954	if (!(br && br->nr))955		return 0;956 957	for (i = 0; i < br->nr; i++) {958		from = entries[i].from;959		to   = entries[i].to;960 961		printed += fprintf(fp, " 0x%"PRIx64, from);962		if (PRINT_FIELD(DSO)) {963			struct addr_location alf, alt;964 965			addr_location__init(&alf);966			addr_location__init(&alt);967			thread__find_map_fb(thread, sample->cpumode, from, &alf);968			thread__find_map_fb(thread, sample->cpumode, to, &alt);969 970			printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);971			printed += fprintf(fp, "/0x%"PRIx64, to);972			printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);973			addr_location__exit(&alt);974			addr_location__exit(&alf);975		} else976			printed += fprintf(fp, "/0x%"PRIx64, to);977 978		printed += print_bstack_flags(fp, entries + i);979	}980 981	return printed;982}983 984static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,985					   struct thread *thread,986					   struct perf_event_attr *attr, FILE *fp)987{988	struct branch_stack *br = sample->branch_stack;989	struct branch_entry *entries = perf_sample__branch_entries(sample);990	u64 i, from, to;991	int printed = 0;992 993	if (!(br && br->nr))994		return 0;995 996	for (i = 0; i < br->nr; i++) {997		struct addr_location alf, alt;998 999		addr_location__init(&alf);1000		addr_location__init(&alt);1001		from = entries[i].from;1002		to   = entries[i].to;1003 1004		thread__find_symbol_fb(thread, sample->cpumode, from, &alf);1005		thread__find_symbol_fb(thread, sample->cpumode, to, &alt);1006 1007		printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);1008		if (PRINT_FIELD(DSO))1009			printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);1010		printed += fprintf(fp, "%c", '/');1011		printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp);1012		if (PRINT_FIELD(DSO))1013			printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);1014		printed += print_bstack_flags(fp, entries + i);1015		addr_location__exit(&alt);1016		addr_location__exit(&alf);1017	}1018 1019	return printed;1020}1021 1022static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,1023					   struct thread *thread,1024					   struct perf_event_attr *attr, FILE *fp)1025{1026	struct branch_stack *br = sample->branch_stack;1027	struct branch_entry *entries = perf_sample__branch_entries(sample);1028	u64 i, from, to;1029	int printed = 0;1030 1031	if (!(br && br->nr))1032		return 0;1033 1034	for (i = 0; i < br->nr; i++) {1035		struct addr_location alf, alt;1036 1037		addr_location__init(&alf);1038		addr_location__init(&alt);1039		from = entries[i].from;1040		to   = entries[i].to;1041 1042		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&1043		    !dso__adjust_symbols(map__dso(alf.map)))1044			from = map__dso_map_ip(alf.map, from);1045 1046		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&1047		    !dso__adjust_symbols(map__dso(alt.map)))1048			to = map__dso_map_ip(alt.map, to);1049 1050		printed += fprintf(fp, " 0x%"PRIx64, from);1051		if (PRINT_FIELD(DSO))1052			printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);1053		printed += fprintf(fp, "/0x%"PRIx64, to);1054		if (PRINT_FIELD(DSO))1055			printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);1056		printed += print_bstack_flags(fp, entries + i);1057		addr_location__exit(&alt);1058		addr_location__exit(&alf);1059	}1060 1061	return printed;1062}1063#define MAXBB 16384UL1064 1065static int grab_bb(u8 *buffer, u64 start, u64 end,1066		    struct machine *machine, struct thread *thread,1067		    bool *is64bit, u8 *cpumode, bool last)1068{1069	long offset, len;1070	struct addr_location al;1071	bool kernel;1072	struct dso *dso;1073	int ret = 0;1074 1075	if (!start || !end)1076		return 0;1077 1078	kernel = machine__kernel_ip(machine, start);1079	if (kernel)1080		*cpumode = PERF_RECORD_MISC_KERNEL;1081	else1082		*cpumode = PERF_RECORD_MISC_USER;1083 1084	/*1085	 * Block overlaps between kernel and user.1086	 * This can happen due to ring filtering1087	 * On Intel CPUs the entry into the kernel is filtered,1088	 * but the exit is not. Let the caller patch it up.1089	 */1090	if (kernel != machine__kernel_ip(machine, end)) {1091		pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end);1092		return -ENXIO;1093	}1094 1095	if (end - start > MAXBB - MAXINSN) {1096		if (last)1097			pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end);1098		else1099			pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start);1100		return 0;1101	}1102 1103	addr_location__init(&al);1104	if (!thread__find_map(thread, *cpumode, start, &al) || (dso = map__dso(al.map)) == NULL) {1105		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);1106		goto out;1107	}1108	if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR) {1109		pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);1110		goto out;1111	}1112 1113	/* Load maps to ensure dso->is_64_bit has been updated */1114	map__load(al.map);1115 1116	offset = map__map_ip(al.map, start);1117	len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer,1118				    end - start + MAXINSN);1119 1120	*is64bit = dso__is_64_bit(dso);1121	if (len <= 0)1122		pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",1123			start, end);1124	ret = len;1125out:1126	addr_location__exit(&al);1127	return ret;1128}1129 1130static int map__fprintf_srccode(struct map *map, u64 addr, FILE *fp, struct srccode_state *state)1131{1132	char *srcfile;1133	int ret = 0;1134	unsigned line;1135	int len;1136	char *srccode;1137	struct dso *dso;1138 1139	if (!map || (dso = map__dso(map)) == NULL)1140		return 0;1141	srcfile = get_srcline_split(dso,1142				    map__rip_2objdump(map, addr),1143				    &line);1144	if (!srcfile)1145		return 0;1146 1147	/* Avoid redundant printing */1148	if (state &&1149	    state->srcfile &&1150	    !strcmp(state->srcfile, srcfile) &&1151	    state->line == line) {1152		free(srcfile);1153		return 0;1154	}1155 1156	srccode = find_sourceline(srcfile, line, &len);1157	if (!srccode)1158		goto out_free_line;1159 1160	ret = fprintf(fp, "|%-8d %.*s", line, len, srccode);1161 1162	if (state) {1163		state->srcfile = srcfile;1164		state->line = line;1165	}1166	return ret;1167 1168out_free_line:1169	free(srcfile);1170	return ret;1171}1172 1173static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr)1174{1175	struct addr_location al;1176	int ret = 0;1177 1178	addr_location__init(&al);1179	thread__find_map(thread, cpumode, addr, &al);1180	if (!al.map)1181		goto out;1182	ret = map__fprintf_srccode(al.map, al.addr, stdout,1183				   thread__srccode_state(thread));1184	if (ret)1185		ret += printf("\n");1186out:1187	addr_location__exit(&al);1188	return ret;1189}1190 1191static int any_dump_insn(struct perf_event_attr *attr __maybe_unused,1192			 struct perf_insn *x, uint64_t ip,1193			 u8 *inbuf, int inlen, int *lenp,1194			 FILE *fp)1195{1196#ifdef HAVE_LIBCAPSTONE_SUPPORT1197	if (PRINT_FIELD(BRSTACKDISASM)) {1198		int printed = fprintf_insn_asm(x->machine, x->thread, x->cpumode, x->is64bit,1199					       (uint8_t *)inbuf, inlen, ip, lenp,1200					       PRINT_INSN_IMM_HEX, fp);1201 1202		if (printed > 0)1203			return printed;1204	}1205#endif1206	return fprintf(fp, "%s", dump_insn(x, ip, inbuf, inlen, lenp));1207}1208 1209static int add_padding(FILE *fp, int printed, int padding)1210{1211	if (printed >= 0 && printed < padding)1212		printed += fprintf(fp, "%*s", padding - printed, "");1213	return printed;1214}1215 1216static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,1217			    struct perf_insn *x, u8 *inbuf, int len,1218			    int insn, FILE *fp, int *total_cycles,1219			    struct perf_event_attr *attr,1220			    struct thread *thread,1221			    struct evsel *evsel,1222			    u64 br_cntr)1223{1224	int ilen = 0;1225	int printed = fprintf(fp, "\t%016" PRIx64 "\t", ip);1226 1227	printed += add_padding(fp, any_dump_insn(attr, x, ip, inbuf, len, &ilen, fp), 30);1228	printed += fprintf(fp, "\t");1229 1230	if (PRINT_FIELD(BRSTACKINSNLEN))1231		printed += fprintf(fp, "ilen: %d\t", ilen);1232 1233	if (PRINT_FIELD(SRCLINE)) {1234		struct addr_location al;1235 1236		addr_location__init(&al);1237		thread__find_map(thread, x->cpumode, ip, &al);1238		printed += map__fprintf_srcline(al.map, al.addr, " srcline: ", fp);1239		printed += fprintf(fp, "\t");1240		addr_location__exit(&al);1241	}1242 1243	if (PRINT_FIELD(BRCNTR)) {1244		struct evsel *pos = evsel__leader(evsel);1245		unsigned int i = 0, j, num, mask, width;1246 1247		perf_env__find_br_cntr_info(evsel__env(evsel), NULL, &width);1248		mask = (1L << width) - 1;1249		printed += fprintf(fp, "br_cntr: ");1250		evlist__for_each_entry_from(evsel->evlist, pos) {1251			if (!(pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS))1252				continue;1253			if (evsel__leader(pos) != evsel__leader(evsel))1254				break;1255 1256			num = (br_cntr >> (i++ * width)) & mask;1257			if (!verbose) {1258				for (j = 0; j < num; j++)1259					printed += fprintf(fp, "%s", pos->abbr_name);1260			} else1261				printed += fprintf(fp, "%s %d ", pos->name, num);1262		}1263		printed += fprintf(fp, "\t");1264	}1265 1266	printed += fprintf(fp, "#%s%s%s%s",1267			      en->flags.predicted ? " PRED" : "",1268			      en->flags.mispred ? " MISPRED" : "",1269			      en->flags.in_tx ? " INTX" : "",1270			      en->flags.abort ? " ABORT" : "");1271	if (en->flags.cycles) {1272		*total_cycles += en->flags.cycles;1273		printed += fprintf(fp, " %d cycles [%d]", en->flags.cycles, *total_cycles);1274		if (insn)1275			printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);1276	}1277 1278	return printed + fprintf(fp, "\n");1279}1280 1281static int ip__fprintf_sym(uint64_t addr, struct thread *thread,1282			   u8 cpumode, int cpu, struct symbol **lastsym,1283			   struct perf_event_attr *attr, FILE *fp)1284{1285	struct addr_location al;1286	int off, printed = 0, ret = 0;1287 1288	addr_location__init(&al);1289	thread__find_map(thread, cpumode, addr, &al);1290 1291	if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)1292		goto out;1293 1294	al.cpu = cpu;1295	al.sym = NULL;1296	if (al.map)1297		al.sym = map__find_symbol(al.map, al.addr);1298 1299	if (!al.sym)1300		goto out;1301 1302	if (al.addr < al.sym->end)1303		off = al.addr - al.sym->start;1304	else1305		off = al.addr - map__start(al.map) - al.sym->start;1306	printed += fprintf(fp, "\t%s", al.sym->name);1307	if (off)1308		printed += fprintf(fp, "%+d", off);1309	printed += fprintf(fp, ":");1310	if (PRINT_FIELD(SRCLINE))1311		printed += map__fprintf_srcline(al.map, al.addr, "\t", fp);1312	printed += fprintf(fp, "\n");1313	*lastsym = al.sym;1314 1315	ret = printed;1316out:1317	addr_location__exit(&al);1318	return ret;1319}1320 1321static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,1322					    struct evsel *evsel,1323					    struct thread *thread,1324					    struct perf_event_attr *attr,1325					    struct machine *machine, FILE *fp)1326{1327	struct branch_stack *br = sample->branch_stack;1328	struct branch_entry *entries = perf_sample__branch_entries(sample);1329	u64 start, end;1330	int i, insn, len, nr, ilen, printed = 0;1331	struct perf_insn x;1332	u8 buffer[MAXBB];1333	unsigned off;1334	struct symbol *lastsym = NULL;1335	int total_cycles = 0;1336	u64 br_cntr = 0;1337 1338	if (!(br && br->nr))1339		return 0;1340	nr = br->nr;1341	if (max_blocks && nr > max_blocks + 1)1342		nr = max_blocks + 1;1343 1344	x.thread = thread;1345	x.machine = machine;1346	x.cpu = sample->cpu;1347 1348	if (PRINT_FIELD(BRCNTR) && sample->branch_stack_cntr)1349		br_cntr = sample->branch_stack_cntr[nr - 1];1350 1351	printed += fprintf(fp, "%c", '\n');1352 1353	/* Handle first from jump, of which we don't know the entry. */1354	len = grab_bb(buffer, entries[nr-1].from,1355			entries[nr-1].from,1356			machine, thread, &x.is64bit, &x.cpumode, false);1357	if (len > 0) {1358		printed += ip__fprintf_sym(entries[nr - 1].from, thread,1359					   x.cpumode, x.cpu, &lastsym, attr, fp);1360		printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1],1361					    &x, buffer, len, 0, fp, &total_cycles,1362					    attr, thread, evsel, br_cntr);1363		if (PRINT_FIELD(SRCCODE))1364			printed += print_srccode(thread, x.cpumode, entries[nr - 1].from);1365	}1366 1367	/* Print all blocks */1368	for (i = nr - 2; i >= 0; i--) {1369		if (entries[i].from || entries[i].to)1370			pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i,1371				 entries[i].from,1372				 entries[i].to);1373		start = entries[i + 1].to;1374		end   = entries[i].from;1375 1376		len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);1377		/* Patch up missing kernel transfers due to ring filters */1378		if (len == -ENXIO && i > 0) {1379			end = entries[--i].from;1380			pr_debug("\tpatching up to %" PRIx64 "-%" PRIx64 "\n", start, end);1381			len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);1382		}1383		if (len <= 0)1384			continue;1385 1386		insn = 0;1387		for (off = 0; off < (unsigned)len; off += ilen) {1388			uint64_t ip = start + off;1389 1390			printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);1391			if (ip == end) {1392				if (PRINT_FIELD(BRCNTR) && sample->branch_stack_cntr)1393					br_cntr = sample->branch_stack_cntr[i];1394				printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp,1395							    &total_cycles, attr, thread, evsel, br_cntr);1396				if (PRINT_FIELD(SRCCODE))1397					printed += print_srccode(thread, x.cpumode, ip);1398				break;1399			} else {1400				ilen = 0;1401				printed += fprintf(fp, "\t%016" PRIx64 "\t", ip);1402				printed += any_dump_insn(attr, &x, ip, buffer + off, len - off, &ilen, fp);1403				if (PRINT_FIELD(BRSTACKINSNLEN))1404					printed += fprintf(fp, "\tilen: %d", ilen);1405				printed += fprintf(fp, "\n");1406				if (ilen == 0)1407					break;1408				if (PRINT_FIELD(SRCCODE))1409					print_srccode(thread, x.cpumode, ip);1410				insn++;1411			}1412		}1413		if (off != end - start)1414			printed += fprintf(fp, "\tmismatch of LBR data and executable\n");1415	}1416 1417	/*1418	 * Hit the branch? In this case we are already done, and the target1419	 * has not been executed yet.1420	 */1421	if (entries[0].from == sample->ip)1422		goto out;1423	if (entries[0].flags.abort)1424		goto out;1425 1426	/*1427	 * Print final block up to sample1428	 *1429	 * Due to pipeline delays the LBRs might be missing a branch1430	 * or two, which can result in very large or negative blocks1431	 * between final branch and sample. When this happens just1432	 * continue walking after the last TO.1433	 */1434	start = entries[0].to;1435	end = sample->ip;1436	if (end < start) {1437		/* Missing jump. Scan 128 bytes for the next branch */1438		end = start + 128;1439	}1440	len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);1441	printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp);1442	if (len <= 0) {1443		/* Print at least last IP if basic block did not work */1444		len = grab_bb(buffer, sample->ip, sample->ip,1445			      machine, thread, &x.is64bit, &x.cpumode, false);1446		if (len <= 0)1447			goto out;1448		ilen = 0;1449		printed += fprintf(fp, "\t%016" PRIx64 "\t", sample->ip);1450		printed += any_dump_insn(attr, &x, sample->ip, buffer, len, &ilen, fp);1451		if (PRINT_FIELD(BRSTACKINSNLEN))1452			printed += fprintf(fp, "\tilen: %d", ilen);1453		printed += fprintf(fp, "\n");1454		if (PRINT_FIELD(SRCCODE))1455			print_srccode(thread, x.cpumode, sample->ip);1456		goto out;1457	}1458	for (off = 0; off <= end - start; off += ilen) {1459		ilen = 0;1460		printed += fprintf(fp, "\t%016" PRIx64 "\t", start + off);1461		printed += any_dump_insn(attr, &x, start + off, buffer + off, len - off, &ilen, fp);1462		if (PRINT_FIELD(BRSTACKINSNLEN))1463			printed += fprintf(fp, "\tilen: %d", ilen);1464		printed += fprintf(fp, "\n");1465		if (ilen == 0)1466			break;1467		if ((attr->branch_sample_type == 0 || attr->branch_sample_type & PERF_SAMPLE_BRANCH_ANY)1468				&& arch_is_uncond_branch(buffer + off, len - off, x.is64bit)1469				&& start + off != sample->ip) {1470			/*1471			 * Hit a missing branch. Just stop.1472			 */1473			printed += fprintf(fp, "\t... not reaching sample ...\n");1474			break;1475		}1476		if (PRINT_FIELD(SRCCODE))1477			print_srccode(thread, x.cpumode, start + off);1478	}1479out:1480	return printed;1481}1482 1483static int perf_sample__fprintf_addr(struct perf_sample *sample,1484				     struct thread *thread,1485				     struct perf_event_attr *attr, FILE *fp)1486{1487	struct addr_location al;1488	int printed = fprintf(fp, "%16" PRIx64, sample->addr);1489 1490	addr_location__init(&al);1491	if (!sample_addr_correlates_sym(attr))1492		goto out;1493 1494	thread__resolve(thread, &al, sample);1495 1496	if (PRINT_FIELD(SYM)) {1497		printed += fprintf(fp, " ");1498		if (PRINT_FIELD(SYMOFFSET))1499			printed += symbol__fprintf_symname_offs(al.sym, &al, fp);1500		else1501			printed += symbol__fprintf_symname(al.sym, fp);1502	}1503 1504	if (PRINT_FIELD(DSO))1505		printed += map__fprintf_dsoname_dsoff(al.map, PRINT_FIELD(DSOFF), al.addr, fp);1506out:1507	addr_location__exit(&al);1508	return printed;1509}1510 1511static const char *resolve_branch_sym(struct perf_sample *sample,1512				      struct evsel *evsel,1513				      struct thread *thread,1514				      struct addr_location *al,1515				      struct addr_location *addr_al,1516				      u64 *ip)1517{1518	struct perf_event_attr *attr = &evsel->core.attr;1519	const char *name = NULL;1520 1521	if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) {1522		if (sample_addr_correlates_sym(attr)) {1523			if (!addr_al->thread)1524				thread__resolve(thread, addr_al, sample);1525			if (addr_al->sym)1526				name = addr_al->sym->name;1527			else1528				*ip = sample->addr;1529		} else {1530			*ip = sample->addr;1531		}1532	} else if (sample->flags & (PERF_IP_FLAG_RETURN | PERF_IP_FLAG_TRACE_END)) {1533		if (al->sym)1534			name = al->sym->name;1535		else1536			*ip = sample->ip;1537	}1538	return name;1539}1540 1541static int perf_sample__fprintf_callindent(struct perf_sample *sample,1542					   struct evsel *evsel,1543					   struct thread *thread,1544					   struct addr_location *al,1545					   struct addr_location *addr_al,1546					   FILE *fp)1547{1548	struct perf_event_attr *attr = &evsel->core.attr;1549	size_t depth = thread_stack__depth(thread, sample->cpu);1550	const char *name = NULL;1551	static int spacing;1552	int len = 0;1553	int dlen = 0;1554	u64 ip = 0;1555 1556	/*1557	 * The 'return' has already been popped off the stack so the depth has1558	 * to be adjusted to match the 'call'.1559	 */1560	if (thread__ts(thread) && sample->flags & PERF_IP_FLAG_RETURN)1561		depth += 1;1562 1563	name = resolve_branch_sym(sample, evsel, thread, al, addr_al, &ip);1564 1565	if (PRINT_FIELD(DSO) && !(PRINT_FIELD(IP) || PRINT_FIELD(ADDR))) {1566		dlen += fprintf(fp, "(");1567		dlen += map__fprintf_dsoname(al->map, fp);1568		dlen += fprintf(fp, ")\t");1569	}1570 1571	if (name)1572		len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);1573	else if (ip)1574		len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip);1575 1576	if (len < 0)1577		return len;1578 1579	/*1580	 * Try to keep the output length from changing frequently so that the1581	 * output lines up more nicely.1582	 */1583	if (len > spacing || (len && len < spacing - 52))1584		spacing = round_up(len + 4, 32);1585 1586	if (len < spacing)1587		len += fprintf(fp, "%*s", spacing - len, "");1588 1589	return len + dlen;1590}1591 1592__weak void arch_fetch_insn(struct perf_sample *sample __maybe_unused,1593			    struct thread *thread __maybe_unused,1594			    struct machine *machine __maybe_unused)1595{1596}1597 1598void script_fetch_insn(struct perf_sample *sample, struct thread *thread,1599		       struct machine *machine)1600{1601	if (sample->insn_len == 0 && native_arch)1602		arch_fetch_insn(sample, thread, machine);1603}1604 1605static int perf_sample__fprintf_insn(struct perf_sample *sample,1606				     struct evsel *evsel,1607				     struct perf_event_attr *attr,1608				     struct thread *thread,1609				     struct machine *machine, FILE *fp,1610				     struct addr_location *al)1611{1612	int printed = 0;1613 1614	script_fetch_insn(sample, thread, machine);1615 1616	if (PRINT_FIELD(INSNLEN))1617		printed += fprintf(fp, " ilen: %d", sample->insn_len);1618	if (PRINT_FIELD(INSN) && sample->insn_len) {1619		printed += fprintf(fp, " insn: ");1620		printed += sample__fprintf_insn_raw(sample, fp);1621	}1622	if (PRINT_FIELD(DISASM) && sample->insn_len) {1623		printed += fprintf(fp, "\t\t");1624		printed += sample__fprintf_insn_asm(sample, thread, machine, fp, al);1625	}1626	if (PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN) || PRINT_FIELD(BRSTACKDISASM))1627		printed += perf_sample__fprintf_brstackinsn(sample, evsel, thread, attr, machine, fp);1628 1629	return printed;1630}1631 1632static int perf_sample__fprintf_ipc(struct perf_sample *sample,1633				    struct perf_event_attr *attr, FILE *fp)1634{1635	unsigned int ipc;1636 1637	if (!PRINT_FIELD(IPC) || !sample->cyc_cnt || !sample->insn_cnt)1638		return 0;1639 1640	ipc = (sample->insn_cnt * 100) / sample->cyc_cnt;1641 1642	return fprintf(fp, " \t IPC: %u.%02u (%" PRIu64 "/%" PRIu64 ") ",1643		       ipc / 100, ipc % 100, sample->insn_cnt, sample->cyc_cnt);1644}1645 1646static int perf_sample__fprintf_bts(struct perf_sample *sample,1647				    struct evsel *evsel,1648				    struct thread *thread,1649				    struct addr_location *al,1650				    struct addr_location *addr_al,1651				    struct machine *machine, FILE *fp)1652{1653	struct perf_event_attr *attr = &evsel->core.attr;1654	unsigned int type = output_type(attr->type);1655	bool print_srcline_last = false;1656	int printed = 0;1657 1658	if (PRINT_FIELD(CALLINDENT))1659		printed += perf_sample__fprintf_callindent(sample, evsel, thread, al, addr_al, fp);1660 1661	/* print branch_from information */1662	if (PRINT_FIELD(IP)) {1663		unsigned int print_opts = output[type].print_ip_opts;1664		struct callchain_cursor *cursor = NULL;1665 1666		if (symbol_conf.use_callchain && sample->callchain) {1667			cursor = get_tls_callchain_cursor();1668			if (thread__resolve_callchain(al->thread, cursor, evsel,1669						      sample, NULL, NULL,1670						      scripting_max_stack))1671				cursor = NULL;1672		}1673		if (cursor == NULL) {1674			printed += fprintf(fp, " ");1675			if (print_opts & EVSEL__PRINT_SRCLINE) {1676				print_srcline_last = true;1677				print_opts &= ~EVSEL__PRINT_SRCLINE;1678			}1679		} else1680			printed += fprintf(fp, "\n");1681 1682		printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor,1683					       symbol_conf.bt_stop_list, fp);1684	}1685 1686	/* print branch_to information */1687	if (PRINT_FIELD(ADDR) ||1688	    ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&1689	     !output[type].user_set)) {1690		printed += fprintf(fp, " => ");1691		printed += perf_sample__fprintf_addr(sample, thread, attr, fp);1692	}1693 1694	printed += perf_sample__fprintf_ipc(sample, attr, fp);1695 1696	if (print_srcline_last)1697		printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);1698 1699	printed += perf_sample__fprintf_insn(sample, evsel, attr, thread, machine, fp, al);1700	printed += fprintf(fp, "\n");1701	if (PRINT_FIELD(SRCCODE)) {1702		int ret = map__fprintf_srccode(al->map, al->addr, stdout,1703					       thread__srccode_state(thread));1704		if (ret) {1705			printed += ret;1706			printed += printf("\n");1707		}1708	}1709	return printed;1710}1711 1712static struct {1713	u32 flags;1714	const char *name;1715} sample_flags[] = {1716	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},1717	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},1718	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"},1719	{PERF_IP_FLAG_BRANCH, "jmp"},1720	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"},1721	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"},1722	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"},1723	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"},1724	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"},1725	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |	PERF_IP_FLAG_INTERRUPT, "hw int"},1726	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"},1727	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"},1728	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"},1729	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMENTRY, "vmentry"},1730	{PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMEXIT, "vmexit"},1731	{0, NULL}1732};1733 1734static const char *sample_flags_to_name(u32 flags)1735{1736	int i;1737 1738	for (i = 0; sample_flags[i].name ; i++) {1739		if (sample_flags[i].flags == flags)1740			return sample_flags[i].name;1741	}1742 1743	return NULL;1744}1745 1746int perf_sample__sprintf_flags(u32 flags, char *str, size_t sz)1747{1748	u32 xf = PERF_IP_FLAG_IN_TX | PERF_IP_FLAG_INTR_DISABLE |1749		 PERF_IP_FLAG_INTR_TOGGLE;1750	const char *chars = PERF_IP_FLAG_CHARS;1751	const size_t n = strlen(PERF_IP_FLAG_CHARS);1752	const char *name = NULL;1753	size_t i, pos = 0;1754	char xs[16] = {0};1755 1756	if (flags & xf)1757		snprintf(xs, sizeof(xs), "(%s%s%s)",1758			 flags & PERF_IP_FLAG_IN_TX ? "x" : "",1759			 flags & PERF_IP_FLAG_INTR_DISABLE ? "D" : "",1760			 flags & PERF_IP_FLAG_INTR_TOGGLE ? "t" : "");1761 1762	name = sample_flags_to_name(flags & ~xf);1763	if (name)1764		return snprintf(str, sz, "%-15s%6s", name, xs);1765 1766	if (flags & PERF_IP_FLAG_TRACE_BEGIN) {1767		name = sample_flags_to_name(flags & ~(xf | PERF_IP_FLAG_TRACE_BEGIN));1768		if (name)1769			return snprintf(str, sz, "tr strt %-7s%6s", name, xs);1770	}1771 1772	if (flags & PERF_IP_FLAG_TRACE_END) {1773		name = sample_flags_to_name(flags & ~(xf | PERF_IP_FLAG_TRACE_END));1774		if (name)1775			return snprintf(str, sz, "tr end  %-7s%6s", name, xs);1776	}1777 1778	for (i = 0; i < n; i++, flags >>= 1) {1779		if ((flags & 1) && pos < sz)1780			str[pos++] = chars[i];1781	}1782	for (; i < 32; i++, flags >>= 1) {1783		if ((flags & 1) && pos < sz)1784			str[pos++] = '?';1785	}1786	if (pos < sz)1787		str[pos] = 0;1788 1789	return pos;1790}1791 1792static int perf_sample__fprintf_flags(u32 flags, FILE *fp)1793{1794	char str[SAMPLE_FLAGS_BUF_SIZE];1795 1796	perf_sample__sprintf_flags(flags, str, sizeof(str));1797	return fprintf(fp, "  %-21s ", str);1798}1799 1800struct printer_data {1801	int line_no;1802	bool hit_nul;1803	bool is_printable;1804};1805 1806static int sample__fprintf_bpf_output(enum binary_printer_ops op,1807				      unsigned int val,1808				      void *extra, FILE *fp)1809{1810	unsigned char ch = (unsigned char)val;1811	struct printer_data *printer_data = extra;1812	int printed = 0;1813 1814	switch (op) {1815	case BINARY_PRINT_DATA_BEGIN:1816		printed += fprintf(fp, "\n");1817		break;1818	case BINARY_PRINT_LINE_BEGIN:1819		printed += fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" :1820						        "           ");1821		break;1822	case BINARY_PRINT_ADDR:1823		printed += fprintf(fp, " %04x:", val);1824		break;1825	case BINARY_PRINT_NUM_DATA:1826		printed += fprintf(fp, " %02x", val);1827		break;1828	case BINARY_PRINT_NUM_PAD:1829		printed += fprintf(fp, "   ");1830		break;1831	case BINARY_PRINT_SEP:1832		printed += fprintf(fp, "  ");1833		break;1834	case BINARY_PRINT_CHAR_DATA:1835		if (printer_data->hit_nul && ch)1836			printer_data->is_printable = false;1837 1838		if (!isprint(ch)) {1839			printed += fprintf(fp, "%c", '.');1840 1841			if (!printer_data->is_printable)1842				break;1843 1844			if (ch == '\0')1845				printer_data->hit_nul = true;1846			else1847				printer_data->is_printable = false;1848		} else {1849			printed += fprintf(fp, "%c", ch);1850		}1851		break;1852	case BINARY_PRINT_CHAR_PAD:1853		printed += fprintf(fp, " ");1854		break;1855	case BINARY_PRINT_LINE_END:1856		printed += fprintf(fp, "\n");1857		printer_data->line_no++;1858		break;1859	case BINARY_PRINT_DATA_END:1860	default:1861		break;1862	}1863 1864	return printed;1865}1866 1867static int perf_sample__fprintf_bpf_output(struct perf_sample *sample, FILE *fp)1868{1869	unsigned int nr_bytes = sample->raw_size;1870	struct printer_data printer_data = {0, false, true};1871	int printed = binary__fprintf(sample->raw_data, nr_bytes, 8,1872				      sample__fprintf_bpf_output, &printer_data, fp);1873 1874	if (printer_data.is_printable && printer_data.hit_nul)1875		printed += fprintf(fp, "%17s \"%s\"\n", "BPF string:", (char *)(sample->raw_data));1876 1877	return printed;1878}1879 1880static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp)1881{1882	if (len > 0 && len < spacing)1883		return fprintf(fp, "%*s", spacing - len, "");1884 1885	return 0;1886}1887 1888static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)1889{1890	return perf_sample__fprintf_spacing(len, 34, fp);1891}1892 1893/* If a value contains only printable ASCII characters padded with NULLs */1894static bool ptw_is_prt(u64 val)1895{1896	char c;1897	u32 i;1898 1899	for (i = 0; i < sizeof(val); i++) {1900		c = ((char *)&val)[i];1901		if (!c)1902			break;1903		if (!isprint(c) || !isascii(c))1904			return false;1905	}1906	for (; i < sizeof(val); i++) {1907		c = ((char *)&val)[i];1908		if (c)1909			return false;1910	}1911	return true;1912}1913 1914static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp)1915{1916	struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);1917	char str[sizeof(u64) + 1] = "";1918	int len;1919	u64 val;1920 1921	if (perf_sample__bad_synth_size(sample, *data))1922		return 0;1923 1924	val = le64_to_cpu(data->payload);1925	if (ptw_is_prt(val)) {1926		memcpy(str, &val, sizeof(val));1927		str[sizeof(val)] = 0;1928	}1929	len = fprintf(fp, " IP: %u payload: %#" PRIx64 " %s ",1930		      data->ip, val, str);1931	return len + perf_sample__fprintf_pt_spacing(len, fp);1932}1933 1934static int perf_sample__fprintf_synth_mwait(struct perf_sample *sample, FILE *fp)1935{1936	struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);1937	int len;1938 1939	if (perf_sample__bad_synth_size(sample, *data))1940		return 0;1941 1942	len = fprintf(fp, " hints: %#x extensions: %#x ",1943		      data->hints, data->extensions);1944	return len + perf_sample__fprintf_pt_spacing(len, fp);1945}1946 1947static int perf_sample__fprintf_synth_pwre(struct perf_sample *sample, FILE *fp)1948{1949	struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);1950	int len;1951 1952	if (perf_sample__bad_synth_size(sample, *data))1953		return 0;1954 1955	len = fprintf(fp, " hw: %u cstate: %u sub-cstate: %u ",1956		      data->hw, data->cstate, data->subcstate);1957	return len + perf_sample__fprintf_pt_spacing(len, fp);1958}1959 1960static int perf_sample__fprintf_synth_exstop(struct perf_sample *sample, FILE *fp)1961{1962	struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);1963	int len;1964 1965	if (perf_sample__bad_synth_size(sample, *data))1966		return 0;1967 1968	len = fprintf(fp, " IP: %u ", data->ip);1969	return len + perf_sample__fprintf_pt_spacing(len, fp);1970}1971 1972static int perf_sample__fprintf_synth_pwrx(struct perf_sample *sample, FILE *fp)1973{1974	struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);1975	int len;1976 1977	if (perf_sample__bad_synth_size(sample, *data))1978		return 0;1979 1980	len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ",1981		     data->deepest_cstate, data->last_cstate,1982		     data->wake_reason);1983	return len + perf_sample__fprintf_pt_spacing(len, fp);1984}1985 1986static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp)1987{1988	struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample);1989	unsigned int percent, freq;1990	int len;1991 1992	if (perf_sample__bad_synth_size(sample, *data))1993		return 0;1994 1995	freq = (le32_to_cpu(data->freq) + 500) / 1000;1996	len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq);1997	if (data->max_nonturbo) {1998		percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;1999		len += fprintf(fp, "(%3u%%) ", percent);2000	}2001	return len + perf_sample__fprintf_pt_spacing(len, fp);2002}2003 2004static int perf_sample__fprintf_synth_psb(struct perf_sample *sample, FILE *fp)2005{2006	struct perf_synth_intel_psb *data = perf_sample__synth_ptr(sample);2007	int len;2008 2009	if (perf_sample__bad_synth_size(sample, *data))2010		return 0;2011 2012	len = fprintf(fp, " psb offs: %#" PRIx64, data->offset);2013	return len + perf_sample__fprintf_pt_spacing(len, fp);2014}2015 2016/* Intel PT Event Trace */2017static int perf_sample__fprintf_synth_evt(struct perf_sample *sample, FILE *fp)2018{2019	struct perf_synth_intel_evt *data = perf_sample__synth_ptr(sample);2020	const char *cfe[32] = {NULL, "INTR", "IRET", "SMI", "RSM", "SIPI",2021			       "INIT", "VMENTRY", "VMEXIT", "VMEXIT_INTR",2022			       "SHUTDOWN", NULL, "UINTR", "UIRET"};2023	const char *evd[64] = {"PFA", "VMXQ", "VMXR"};2024	const char *s;2025	int len, i;2026 2027	if (perf_sample__bad_synth_size(sample, *data))2028		return 0;2029 2030	s = cfe[data->type];2031	if (s) {2032		len = fprintf(fp, " cfe: %s IP: %d vector: %u",2033			      s, data->ip, data->vector);2034	} else {2035		len = fprintf(fp, " cfe: %u IP: %d vector: %u",2036			      data->type, data->ip, data->vector);2037	}2038	for (i = 0; i < data->evd_cnt; i++) {2039		unsigned int et = data->evd[i].evd_type & 0x3f;2040 2041		s = evd[et];2042		if (s) {2043			len += fprintf(fp, " %s: %#" PRIx64,2044				       s, data->evd[i].payload);2045		} else {2046			len += fprintf(fp, " EVD_%u: %#" PRIx64,2047				       et, data->evd[i].payload);2048		}2049	}2050	return len + perf_sample__fprintf_pt_spacing(len, fp);2051}2052 2053static int perf_sample__fprintf_synth_iflag_chg(struct perf_sample *sample, FILE *fp)2054{2055	struct perf_synth_intel_iflag_chg *data = perf_sample__synth_ptr(sample);2056	int len;2057 2058	if (perf_sample__bad_synth_size(sample, *data))2059		return 0;2060 2061	len = fprintf(fp, " IFLAG: %d->%d %s branch", !data->iflag, data->iflag,2062		      data->via_branch ? "via" : "non");2063	return len + perf_sample__fprintf_pt_spacing(len, fp);2064}2065 2066static int perf_sample__fprintf_synth(struct perf_sample *sample,2067				      struct evsel *evsel, FILE *fp)2068{2069	switch (evsel->core.attr.config) {2070	case PERF_SYNTH_INTEL_PTWRITE:2071		return perf_sample__fprintf_synth_ptwrite(sample, fp);2072	case PERF_SYNTH_INTEL_MWAIT:2073		return perf_sample__fprintf_synth_mwait(sample, fp);2074	case PERF_SYNTH_INTEL_PWRE:2075		return perf_sample__fprintf_synth_pwre(sample, fp);2076	case PERF_SYNTH_INTEL_EXSTOP:2077		return perf_sample__fprintf_synth_exstop(sample, fp);2078	case PERF_SYNTH_INTEL_PWRX:2079		return perf_sample__fprintf_synth_pwrx(sample, fp);2080	case PERF_SYNTH_INTEL_CBR:2081		return perf_sample__fprintf_synth_cbr(sample, fp);2082	case PERF_SYNTH_INTEL_PSB:2083		return perf_sample__fprintf_synth_psb(sample, fp);2084	case PERF_SYNTH_INTEL_EVT:2085		return perf_sample__fprintf_synth_evt(sample, fp);2086	case PERF_SYNTH_INTEL_IFLAG_CHG:2087		return perf_sample__fprintf_synth_iflag_chg(sample, fp);2088	default:2089		break;2090	}2091 2092	return 0;2093}2094 2095static int evlist__max_name_len(struct evlist *evlist)2096{2097	struct evsel *evsel;2098	int max = 0;2099 2100	evlist__for_each_entry(evlist, evsel) {2101		int len = strlen(evsel__name(evsel));2102 2103		max = MAX(len, max);2104	}2105 2106	return max;2107}2108 2109static int data_src__fprintf(u64 data_src, FILE *fp)2110{2111	struct mem_info *mi = mem_info__new();2112	char decode[100];2113	char out[100];2114	static int maxlen;2115	int len;2116 2117	if (!mi)2118		return -ENOMEM;2119 2120	mem_info__data_src(mi)->val = data_src;2121	perf_script__meminfo_scnprintf(decode, 100, mi);2122	mem_info__put(mi);2123 2124	len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode);2125	if (maxlen < len)2126		maxlen = len;2127 2128	return fprintf(fp, "%-*s", maxlen, out);2129}2130 2131struct metric_ctx {2132	struct perf_sample	*sample;2133	struct thread		*thread;2134	struct evsel	*evsel;2135	FILE 			*fp;2136};2137 2138static void script_print_metric(struct perf_stat_config *config __maybe_unused,2139				void *ctx, const char *color,2140			        const char *fmt,2141			        const char *unit, double val)2142{2143	struct metric_ctx *mctx = ctx;2144 2145	if (!fmt)2146		return;2147	perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,2148				   PERF_RECORD_SAMPLE, mctx->fp);2149	fputs("\tmetric: ", mctx->fp);2150	if (color)2151		color_fprintf(mctx->fp, color, fmt, val);2152	else2153		printf(fmt, val);2154	fprintf(mctx->fp, " %s\n", unit);2155}2156 2157static void script_new_line(struct perf_stat_config *config __maybe_unused,2158			    void *ctx)2159{2160	struct metric_ctx *mctx = ctx;2161 2162	perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,2163				   PERF_RECORD_SAMPLE, mctx->fp);2164	fputs("\tmetric: ", mctx->fp);2165}2166 2167static void perf_sample__fprint_metric(struct perf_script *script,2168				       struct thread *thread,2169				       struct evsel *evsel,2170				       struct perf_sample *sample,2171				       FILE *fp)2172{2173	struct evsel *leader = evsel__leader(evsel);2174	struct perf_stat_output_ctx ctx = {2175		.print_metric = script_print_metric,2176		.new_line = script_new_line,2177		.ctx = &(struct metric_ctx) {2178				.sample = sample,2179				.thread = thread,2180				.evsel  = evsel,2181				.fp     = fp,2182			 },2183		.force_header = false,2184	};2185	struct evsel *ev2;2186	u64 val;2187 2188	if (!evsel->stats)2189		evlist__alloc_stats(&stat_config, script->session->evlist, /*alloc_raw=*/false);2190	if (evsel_script(leader)->gnum++ == 0)2191		perf_stat__reset_shadow_stats();2192	val = sample->period * evsel->scale;2193	evsel_script(evsel)->val = val;2194	if (evsel_script(leader)->gnum == leader->core.nr_members) {2195		for_each_group_member (ev2, leader) {2196			perf_stat__print_shadow_stats(&stat_config, ev2,2197						      evsel_script(ev2)->val,2198						      sample->cpu,2199						      &ctx,2200						      NULL);2201		}2202		evsel_script(leader)->gnum = 0;2203	}2204}2205 2206static bool show_event(struct perf_sample *sample,2207		       struct evsel *evsel,2208		       struct thread *thread,2209		       struct addr_location *al,2210		       struct addr_location *addr_al)2211{2212	int depth = thread_stack__depth(thread, sample->cpu);2213 2214	if (!symbol_conf.graph_function)2215		return true;2216 2217	if (thread__filter(thread)) {2218		if (depth <= thread__filter_entry_depth(thread)) {2219			thread__set_filter(thread, false);2220			return false;2221		}2222		return true;2223	} else {2224		const char *s = symbol_conf.graph_function;2225		u64 ip;2226		const char *name = resolve_branch_sym(sample, evsel, thread, al, addr_al,2227				&ip);2228		unsigned nlen;2229 2230		if (!name)2231			return false;2232		nlen = strlen(name);2233		while (*s) {2234			unsigned len = strcspn(s, ",");2235			if (nlen == len && !strncmp(name, s, len)) {2236				thread__set_filter(thread, true);2237				thread__set_filter_entry_depth(thread, depth);2238				return true;2239			}2240			s += len;2241			if (*s == ',')2242				s++;2243		}2244		return false;2245	}2246}2247 2248static void process_event(struct perf_script *script,2249			  struct perf_sample *sample, struct evsel *evsel,2250			  struct addr_location *al,2251			  struct addr_location *addr_al,2252			  struct machine *machine)2253{2254	struct thread *thread = al->thread;2255	struct perf_event_attr *attr = &evsel->core.attr;2256	unsigned int type = output_type(attr->type);2257	struct evsel_script *es = evsel->priv;2258	FILE *fp = es->fp;2259	char str[PAGE_SIZE_NAME_LEN];2260	const char *arch = perf_env__arch(machine->env);2261 2262	if (output[type].fields == 0)2263		return;2264 2265	++es->samples;2266 2267	perf_sample__fprintf_start(script, sample, thread, evsel,2268				   PERF_RECORD_SAMPLE, fp);2269 2270	if (PRINT_FIELD(PERIOD))2271		fprintf(fp, "%10" PRIu64 " ", sample->period);2272 2273	if (PRINT_FIELD(EVNAME)) {2274		const char *evname = evsel__name(evsel);2275 2276		if (!script->name_width)2277			script->name_width = evlist__max_name_len(script->session->evlist);2278 2279		fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]");2280	}2281 2282	if (print_flags)2283		perf_sample__fprintf_flags(sample->flags, fp);2284 2285	if (is_bts_event(attr)) {2286		perf_sample__fprintf_bts(sample, evsel, thread, al, addr_al, machine, fp);2287		return;2288	}2289#ifdef HAVE_LIBTRACEEVENT2290	if (PRINT_FIELD(TRACE) && sample->raw_data) {2291		event_format__fprintf(evsel->tp_format, sample->cpu,2292				      sample->raw_data, sample->raw_size, fp);2293	}2294#endif2295	if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))2296		perf_sample__fprintf_synth(sample, evsel, fp);2297 2298	if (PRINT_FIELD(ADDR))2299		perf_sample__fprintf_addr(sample, thread, attr, fp);2300 2301	if (PRINT_FIELD(DATA_SRC))2302		data_src__fprintf(sample->data_src, fp);2303 2304	if (PRINT_FIELD(WEIGHT))2305		fprintf(fp, "%16" PRIu64, sample->weight);2306 2307	if (PRINT_FIELD(INS_LAT))2308		fprintf(fp, "%16" PRIu16, sample->ins_lat);2309 2310	if (PRINT_FIELD(RETIRE_LAT))2311		fprintf(fp, "%16" PRIu16, sample->retire_lat);2312 2313	if (PRINT_FIELD(CGROUP)) {2314		const char *cgrp_name;2315		struct cgroup *cgrp = cgroup__find(machine->env,2316						   sample->cgroup);2317		if (cgrp != NULL)2318			cgrp_name = cgrp->name;2319		else2320			cgrp_name = "unknown";2321		fprintf(fp, " %s", cgrp_name);2322	}2323 2324	if (PRINT_FIELD(IP)) {2325		struct callchain_cursor *cursor = NULL;2326 2327		if (script->stitch_lbr)2328			thread__set_lbr_stitch_enable(al->thread, true);2329 2330		if (symbol_conf.use_callchain && sample->callchain) {2331			cursor = get_tls_callchain_cursor();2332			if (thread__resolve_callchain(al->thread, cursor, evsel,2333						      sample, NULL, NULL,2334						      scripting_max_stack))2335				cursor = NULL;2336		}2337		fputc(cursor ? '\n' : ' ', fp);2338		sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor,2339				    symbol_conf.bt_stop_list, fp);2340	}2341 2342	if (PRINT_FIELD(IREGS))2343		perf_sample__fprintf_iregs(sample, attr, arch, fp);2344 2345	if (PRINT_FIELD(UREGS))2346		perf_sample__fprintf_uregs(sample, attr, arch, fp);2347 2348	if (PRINT_FIELD(BRSTACK))2349		perf_sample__fprintf_brstack(sample, thread, attr, fp);2350	else if (PRINT_FIELD(BRSTACKSYM))2351		perf_sample__fprintf_brstacksym(sample, thread, attr, fp);2352	else if (PRINT_FIELD(BRSTACKOFF))2353		perf_sample__fprintf_brstackoff(sample, thread, attr, fp);2354 2355	if (evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))2356		perf_sample__fprintf_bpf_output(sample, fp);2357	perf_sample__fprintf_insn(sample, evsel, attr, thread, machine, fp, al);2358 2359	if (PRINT_FIELD(PHYS_ADDR))2360		fprintf(fp, "%16" PRIx64, sample->phys_addr);2361 2362	if (PRINT_FIELD(DATA_PAGE_SIZE))2363		fprintf(fp, " %s", get_page_size_name(sample->data_page_size, str));2364 2365	if (PRINT_FIELD(CODE_PAGE_SIZE))2366		fprintf(fp, " %s", get_page_size_name(sample->code_page_size, str));2367 2368	perf_sample__fprintf_ipc(sample, attr, fp);2369 2370	fprintf(fp, "\n");2371 2372	if (PRINT_FIELD(SRCCODE)) {2373		if (map__fprintf_srccode(al->map, al->addr, stdout,2374					 thread__srccode_state(thread)))2375			printf("\n");2376	}2377 2378	if (PRINT_FIELD(METRIC))2379		perf_sample__fprint_metric(script, thread, evsel, sample, fp);2380 2381	if (verbose > 0)2382		fflush(fp);2383}2384 2385static struct scripting_ops	*scripting_ops;2386 2387static void __process_stat(struct evsel *counter, u64 tstamp)2388{2389	int nthreads = perf_thread_map__nr(counter->core.threads);2390	int idx, thread;2391	struct perf_cpu cpu;2392	static int header_printed;2393 2394	if (!header_printed) {2395		printf("%3s %8s %15s %15s %15s %15s %s\n",2396		       "CPU", "THREAD", "VAL", "ENA", "RUN", "TIME", "EVENT");2397		header_printed = 1;2398	}2399 2400	for (thread = 0; thread < nthreads; thread++) {2401		perf_cpu_map__for_each_cpu(cpu, idx, evsel__cpus(counter)) {2402			struct perf_counts_values *counts;2403 2404			counts = perf_counts(counter->counts, idx, thread);2405 2406			printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n",2407				cpu.cpu,2408				perf_thread_map__pid(counter->core.threads, thread),2409				counts->val,2410				counts->ena,2411				counts->run,2412				tstamp,2413				evsel__name(counter));2414		}2415	}2416}2417 2418static void process_stat(struct evsel *counter, u64 tstamp)2419{2420	if (scripting_ops && scripting_ops->process_stat)2421		scripting_ops->process_stat(&stat_config, counter, tstamp);2422	else2423		__process_stat(counter, tstamp);2424}2425 2426static void process_stat_interval(u64 tstamp)2427{2428	if (scripting_ops && scripting_ops->process_stat_interval)2429		scripting_ops->process_stat_interval(tstamp);2430}2431 2432static void setup_scripting(void)2433{2434#ifdef HAVE_LIBTRACEEVENT2435	setup_perl_scripting();2436#endif2437	setup_python_scripting();2438}2439 2440static int flush_scripting(void)2441{2442	return scripting_ops ? scripting_ops->flush_script() : 0;2443}2444 2445static int cleanup_scripting(void)2446{2447	pr_debug("\nperf script stopped\n");2448 2449	return scripting_ops ? scripting_ops->stop_script() : 0;2450}2451 2452static bool filter_cpu(struct perf_sample *sample)2453{2454	if (cpu_list && sample->cpu != (u32)-1)2455		return !test_bit(sample->cpu, cpu_bitmap);2456	return false;2457}2458 2459static int process_sample_event(const struct perf_tool *tool,2460				union perf_event *event,2461				struct perf_sample *sample,2462				struct evsel *evsel,2463				struct machine *machine)2464{2465	struct perf_script *scr = container_of(tool, struct perf_script, tool);2466	struct addr_location al;2467	struct addr_location addr_al;2468	int ret = 0;2469 2470	/* Set thread to NULL to indicate addr_al and al are not initialized */2471	addr_location__init(&al);2472	addr_location__init(&addr_al);2473 2474	ret = dlfilter__filter_event_early(dlfilter, event, sample, evsel, machine, &al, &addr_al);2475	if (ret) {2476		if (ret > 0)2477			ret = 0;2478		goto out_put;2479	}2480 2481	if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num,2482					  sample->time)) {2483		goto out_put;2484	}2485 2486	if (debug_mode) {2487		if (sample->time < last_timestamp) {2488			pr_err("Samples misordered, previous: %" PRIu642489				" this: %" PRIu64 "\n", last_timestamp,2490				sample->time);2491			nr_unordered++;2492		}2493		last_timestamp = sample->time;2494		goto out_put;2495	}2496 2497	if (filter_cpu(sample))2498		goto out_put;2499 2500	if (!al.thread && machine__resolve(machine, &al, sample) < 0) {2501		pr_err("problem processing %d event, skipping it.\n",2502		       event->header.type);2503		ret = -1;2504		goto out_put;2505	}2506 2507	if (al.filtered)2508		goto out_put;2509 2510	if (!show_event(sample, evsel, al.thread, &al, &addr_al))2511		goto out_put;2512 2513	if (evswitch__discard(&scr->evswitch, evsel))2514		goto out_put;2515 2516	ret = dlfilter__filter_event(dlfilter, event, sample, evsel, machine, &al, &addr_al);2517	if (ret) {2518		if (ret > 0)2519			ret = 0;2520		goto out_put;2521	}2522 2523	if (scripting_ops) {2524		struct addr_location *addr_al_ptr = NULL;2525 2526		if ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&2527		    sample_addr_correlates_sym(&evsel->core.attr)) {2528			if (!addr_al.thread)2529				thread__resolve(al.thread, &addr_al, sample);2530			addr_al_ptr = &addr_al;2531		}2532		scripting_ops->process_event(event, sample, evsel, &al, addr_al_ptr);2533	} else {2534		process_event(scr, sample, evsel, &al, &addr_al, machine);2535	}2536 2537out_put:2538	addr_location__exit(&addr_al);2539	addr_location__exit(&al);2540	return ret;2541}2542 2543// Used when scr->per_event_dump is not set2544static struct evsel_script es_stdout;2545 2546static int process_attr(const struct perf_tool *tool, union perf_event *event,2547			struct evlist **pevlist)2548{2549	struct perf_script *scr = container_of(tool, struct perf_script, tool);2550	struct evlist *evlist;2551	struct evsel *evsel, *pos;2552	u64 sample_type;2553	int err;2554 2555	err = perf_event__process_attr(tool, event, pevlist);2556	if (err)2557		return err;2558 2559	evlist = *pevlist;2560	evsel = evlist__last(*pevlist);2561 2562	if (!evsel->priv) {2563		if (scr->per_event_dump) {2564			evsel->priv = evsel_script__new(evsel, scr->session->data);2565			if (!evsel->priv)2566				return -ENOMEM;2567		} else { // Replicate what is done in perf_script__setup_per_event_dump()2568			es_stdout.fp = stdout;2569			evsel->priv = &es_stdout;2570		}2571	}2572 2573	if (evsel->core.attr.type >= PERF_TYPE_MAX &&2574	    evsel->core.attr.type != PERF_TYPE_SYNTH)2575		return 0;2576 2577	evlist__for_each_entry(evlist, pos) {2578		if (pos->core.attr.type == evsel->core.attr.type && pos != evsel)2579			return 0;2580	}2581 2582	if (evsel->core.attr.sample_type) {2583		err = evsel__check_attr(evsel, scr->session);2584		if (err)2585			return err;2586	}2587 2588	/*2589	 * Check if we need to enable callchains based2590	 * on events sample_type.2591	 */2592	sample_type = evlist__combined_sample_type(evlist);2593	callchain_param_setup(sample_type, perf_env__arch((*pevlist)->env));2594 2595	/* Enable fields for callchain entries */2596	if (symbol_conf.use_callchain &&2597	    (sample_type & PERF_SAMPLE_CALLCHAIN ||2598	     sample_type & PERF_SAMPLE_BRANCH_STACK ||2599	     (sample_type & PERF_SAMPLE_REGS_USER &&2600	      sample_type & PERF_SAMPLE_STACK_USER))) {2601		int type = output_type(evsel->core.attr.type);2602 2603		if (!(output[type].user_unset_fields & PERF_OUTPUT_IP))2604			output[type].fields |= PERF_OUTPUT_IP;2605		if (!(output[type].user_unset_fields & PERF_OUTPUT_SYM))2606			output[type].fields |= PERF_OUTPUT_SYM;2607	}2608	set_print_ip_opts(&evsel->core.attr);2609	return 0;2610}2611 2612static int print_event_with_time(const struct perf_tool *tool,2613				 union perf_event *event,2614				 struct perf_sample *sample,2615				 struct machine *machine,2616				 pid_t pid, pid_t tid, u64 timestamp)2617{2618	struct perf_script *script = container_of(tool, struct perf_script, tool);2619	struct perf_session *session = script->session;2620	struct evsel *evsel = evlist__id2evsel(session->evlist, sample->id);2621	struct thread *thread = NULL;2622 2623	if (evsel && !evsel->core.attr.sample_id_all) {2624		sample->cpu = 0;2625		sample->time = timestamp;2626		sample->pid = pid;2627		sample->tid = tid;2628	}2629 2630	if (filter_cpu(sample))2631		return 0;2632 2633	if (tid != -1)2634		thread = machine__findnew_thread(machine, pid, tid);2635 2636	if (evsel) {2637		perf_sample__fprintf_start(script, sample, thread, evsel,2638					   event->header.type, stdout);2639	}2640 2641	perf_event__fprintf(event, machine, stdout);2642 2643	thread__put(thread);2644 2645	return 0;2646}2647 2648static int print_event(const struct perf_tool *tool, union perf_event *event,2649		       struct perf_sample *sample, struct machine *machine,2650		       pid_t pid, pid_t tid)2651{2652	return print_event_with_time(tool, event, sample, machine, pid, tid, 0);2653}2654 2655static int process_comm_event(const struct perf_tool *tool,2656			      union perf_event *event,2657			      struct perf_sample *sample,2658			      struct machine *machine)2659{2660	if (perf_event__process_comm(tool, event, sample, machine) < 0)2661		return -1;2662 2663	return print_event(tool, event, sample, machine, event->comm.pid,2664			   event->comm.tid);2665}2666 2667static int process_namespaces_event(const struct perf_tool *tool,2668				    union perf_event *event,2669				    struct perf_sample *sample,2670				    struct machine *machine)2671{2672	if (perf_event__process_namespaces(tool, event, sample, machine) < 0)2673		return -1;2674 2675	return print_event(tool, event, sample, machine, event->namespaces.pid,2676			   event->namespaces.tid);2677}2678 2679static int process_cgroup_event(const struct perf_tool *tool,2680				union perf_event *event,2681				struct perf_sample *sample,2682				struct machine *machine)2683{2684	if (perf_event__process_cgroup(tool, event, sample, machine) < 0)2685		return -1;2686 2687	return print_event(tool, event, sample, machine, sample->pid,2688			    sample->tid);2689}2690 2691static int process_fork_event(const struct perf_tool *tool,2692			      union perf_event *event,2693			      struct perf_sample *sample,2694			      struct machine *machine)2695{2696	if (perf_event__process_fork(tool, event, sample, machine) < 0)2697		return -1;2698 2699	return print_event_with_time(tool, event, sample, machine,2700				     event->fork.pid, event->fork.tid,2701				     event->fork.time);2702}2703static int process_exit_event(const struct perf_tool *tool,2704			      union perf_event *event,2705			      struct perf_sample *sample,2706			      struct machine *machine)2707{2708	/* Print before 'exit' deletes anything */2709	if (print_event_with_time(tool, event, sample, machine, event->fork.pid,2710				  event->fork.tid, event->fork.time))2711		return -1;2712 2713	return perf_event__process_exit(tool, event, sample, machine);2714}2715 2716static int process_mmap_event(const struct perf_tool *tool,2717			      union perf_event *event,2718			      struct perf_sample *sample,2719			      struct machine *machine)2720{2721	if (perf_event__process_mmap(tool, event, sample, machine) < 0)2722		return -1;2723 2724	return print_event(tool, event, sample, machine, event->mmap.pid,2725			   event->mmap.tid);2726}2727 2728static int process_mmap2_event(const struct perf_tool *tool,2729			      union perf_event *event,2730			      struct perf_sample *sample,2731			      struct machine *machine)2732{2733	if (perf_event__process_mmap2(tool, event, sample, machine) < 0)2734		return -1;2735 2736	return print_event(tool, event, sample, machine, event->mmap2.pid,2737			   event->mmap2.tid);2738}2739 2740static int process_switch_event(const struct perf_tool *tool,2741				union perf_event *event,2742				struct perf_sample *sample,2743				struct machine *machine)2744{2745	struct perf_script *script = container_of(tool, struct perf_script, tool);2746 2747	if (perf_event__process_switch(tool, event, sample, machine) < 0)2748		return -1;2749 2750	if (scripting_ops && scripting_ops->process_switch && !filter_cpu(sample))2751		scripting_ops->process_switch(event, sample, machine);2752 2753	if (!script->show_switch_events)2754		return 0;2755 2756	return print_event(tool, event, sample, machine, sample->pid,2757			   sample->tid);2758}2759 2760static int process_auxtrace_error(struct perf_session *session,2761				  union perf_event *event)2762{2763	if (scripting_ops && scripting_ops->process_auxtrace_error) {2764		scripting_ops->process_auxtrace_error(session, event);2765		return 0;2766	}2767 2768	return perf_event__process_auxtrace_error(session, event);2769}2770 2771static int2772process_lost_event(const struct perf_tool *tool,2773		   union perf_event *event,2774		   struct perf_sample *sample,2775		   struct machine *machine)2776{2777	return print_event(tool, event, sample, machine, sample->pid,2778			   sample->tid);2779}2780 2781static int2782process_throttle_event(const struct perf_tool *tool __maybe_unused,2783		       union perf_event *event,2784		       struct perf_sample *sample,2785		       struct machine *machine)2786{2787	if (scripting_ops && scripting_ops->process_throttle)2788		scripting_ops->process_throttle(event, sample, machine);2789	return 0;2790}2791 2792static int2793process_finished_round_event(const struct perf_tool *tool __maybe_unused,2794			     union perf_event *event,2795			     struct ordered_events *oe __maybe_unused)2796 2797{2798	perf_event__fprintf(event, NULL, stdout);2799	return 0;2800}2801 2802static int2803process_bpf_events(const struct perf_tool *tool __maybe_unused,2804		   union perf_event *event,2805		   struct perf_sample *sample,2806		   struct machine *machine)2807{2808	if (machine__process_ksymbol(machine, event, sample) < 0)2809		return -1;2810 2811	return print_event(tool, event, sample, machine, sample->pid,2812			   sample->tid);2813}2814 2815static int process_text_poke_events(const struct perf_tool *tool,2816				    union perf_event *event,2817				    struct perf_sample *sample,2818				    struct machine *machine)2819{2820	if (perf_event__process_text_poke(tool, event, sample, machine) < 0)2821		return -1;2822 2823	return print_event(tool, event, sample, machine, sample->pid,2824			   sample->tid);2825}2826 2827static void sig_handler(int sig __maybe_unused)2828{2829	session_done = 1;2830}2831 2832static void perf_script__fclose_per_event_dump(struct perf_script *script)2833{2834	struct evlist *evlist = script->session->evlist;2835	struct evsel *evsel;2836 2837	evlist__for_each_entry(evlist, evsel) {2838		if (!evsel->priv)2839			break;2840		evsel_script__delete(evsel->priv);2841		evsel->priv = NULL;2842	}2843}2844 2845static int perf_script__fopen_per_event_dump(struct perf_script *script)2846{2847	struct evsel *evsel;2848 2849	evlist__for_each_entry(script->session->evlist, evsel) {2850		/*2851		 * Already setup? I.e. we may be called twice in cases like2852		 * Intel PT, one for the intel_pt// and dummy events, then2853		 * for the evsels synthesized from the auxtrace info.2854		 *2855		 * Ses perf_script__process_auxtrace_info.2856		 */2857		if (evsel->priv != NULL)2858			continue;2859 2860		evsel->priv = evsel_script__new(evsel, script->session->data);2861		if (evsel->priv == NULL)2862			goto out_err_fclose;2863	}2864 2865	return 0;2866 2867out_err_fclose:2868	perf_script__fclose_per_event_dump(script);2869	return -1;2870}2871 2872static int perf_script__setup_per_event_dump(struct perf_script *script)2873{2874	struct evsel *evsel;2875 2876	if (script->per_event_dump)2877		return perf_script__fopen_per_event_dump(script);2878 2879	es_stdout.fp = stdout;2880 2881	evlist__for_each_entry(script->session->evlist, evsel)2882		evsel->priv = &es_stdout;2883 2884	return 0;2885}2886 2887static void perf_script__exit_per_event_dump_stats(struct perf_script *script)2888{2889	struct evsel *evsel;2890 2891	evlist__for_each_entry(script->session->evlist, evsel) {2892		struct evsel_script *es = evsel->priv;2893 2894		evsel_script__fprintf(es, stdout);2895		evsel_script__delete(es);2896		evsel->priv = NULL;2897	}2898}2899 2900static void perf_script__exit(struct perf_script *script)2901{2902	perf_thread_map__put(script->threads);2903	perf_cpu_map__put(script->cpus);2904}2905 2906static int __cmd_script(struct perf_script *script)2907{2908	int ret;2909 2910	signal(SIGINT, sig_handler);2911 2912	/* override event processing functions */2913	if (script->show_task_events) {2914		script->tool.comm = process_comm_event;2915		script->tool.fork = process_fork_event;2916		script->tool.exit = process_exit_event;2917	}2918	if (script->show_mmap_events) {2919		script->tool.mmap = process_mmap_event;2920		script->tool.mmap2 = process_mmap2_event;2921	}2922	if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch))2923		script->tool.context_switch = process_switch_event;2924	if (scripting_ops && scripting_ops->process_auxtrace_error)2925		script->tool.auxtrace_error = process_auxtrace_error;2926	if (script->show_namespace_events)2927		script->tool.namespaces = process_namespaces_event;2928	if (script->show_cgroup_events)2929		script->tool.cgroup = process_cgroup_event;2930	if (script->show_lost_events)2931		script->tool.lost = process_lost_event;2932	if (script->show_round_events) {2933		script->tool.ordered_events = false;2934		script->tool.finished_round = process_finished_round_event;2935	}2936	if (script->show_bpf_events) {2937		script->tool.ksymbol = process_bpf_events;2938		script->tool.bpf     = process_bpf_events;2939	}2940	if (script->show_text_poke_events) {2941		script->tool.ksymbol   = process_bpf_events;2942		script->tool.text_poke = process_text_poke_events;2943	}2944 2945	if (perf_script__setup_per_event_dump(script)) {2946		pr_err("Couldn't create the per event dump files\n");2947		return -1;2948	}2949 2950	ret = perf_session__process_events(script->session);2951 2952	if (script->per_event_dump)2953		perf_script__exit_per_event_dump_stats(script);2954 2955	if (debug_mode)2956		pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);2957 2958	return ret;2959}2960 2961struct script_spec {2962	struct list_head	node;2963	struct scripting_ops	*ops;2964	char			spec[];2965};2966 2967static LIST_HEAD(script_specs);2968 2969static struct script_spec *script_spec__new(const char *spec,2970					    struct scripting_ops *ops)2971{2972	struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);2973 2974	if (s != NULL) {2975		strcpy(s->spec, spec);2976		s->ops = ops;2977	}2978 2979	return s;2980}2981 2982static void script_spec__add(struct script_spec *s)2983{2984	list_add_tail(&s->node, &script_specs);2985}2986 2987static struct script_spec *script_spec__find(const char *spec)2988{2989	struct script_spec *s;2990 2991	list_for_each_entry(s, &script_specs, node)2992		if (strcasecmp(s->spec, spec) == 0)2993			return s;2994	return NULL;2995}2996 2997int script_spec_register(const char *spec, struct scripting_ops *ops)2998{2999	struct script_spec *s;3000 3001	s = script_spec__find(spec);3002	if (s)3003		return -1;3004 3005	s = script_spec__new(spec, ops);3006	if (!s)3007		return -1;3008	else3009		script_spec__add(s);3010 3011	return 0;3012}3013 3014static struct scripting_ops *script_spec__lookup(const char *spec)3015{3016	struct script_spec *s = script_spec__find(spec);3017	if (!s)3018		return NULL;3019 3020	return s->ops;3021}3022 3023static void list_available_languages(void)3024{3025	struct script_spec *s;3026 3027	fprintf(stderr, "\n");3028	fprintf(stderr, "Scripting language extensions (used in "3029		"perf script -s [spec:]script.[spec]):\n\n");3030 3031	list_for_each_entry(s, &script_specs, node)3032		fprintf(stderr, "  %-42s [%s]\n", s->spec, s->ops->name);3033 3034	fprintf(stderr, "\n");3035}3036 3037/* Find script file relative to current directory or exec path */3038static char *find_script(const char *script)3039{3040	char path[PATH_MAX];3041 3042	if (!scripting_ops) {3043		const char *ext = strrchr(script, '.');3044 3045		if (!ext)3046			return NULL;3047 3048		scripting_ops = script_spec__lookup(++ext);3049		if (!scripting_ops)3050			return NULL;3051	}3052 3053	if (access(script, R_OK)) {3054		char *exec_path = get_argv_exec_path();3055 3056		if (!exec_path)3057			return NULL;3058		snprintf(path, sizeof(path), "%s/scripts/%s/%s",3059			 exec_path, scripting_ops->dirname, script);3060		free(exec_path);3061		script = path;3062		if (access(script, R_OK))3063			return NULL;3064	}3065	return strdup(script);3066}3067 3068static int parse_scriptname(const struct option *opt __maybe_unused,3069			    const char *str, int unset __maybe_unused)3070{3071	char spec[PATH_MAX];3072	const char *script, *ext;3073	int len;3074 3075	if (strcmp(str, "lang") == 0) {3076		list_available_languages();3077		exit(0);3078	}3079 3080	script = strchr(str, ':');3081	if (script) {3082		len = script - str;3083		if (len >= PATH_MAX) {3084			fprintf(stderr, "invalid language specifier");3085			return -1;3086		}3087		strncpy(spec, str, len);3088		spec[len] = '\0';3089		scripting_ops = script_spec__lookup(spec);3090		if (!scripting_ops) {3091			fprintf(stderr, "invalid language specifier");3092			return -1;3093		}3094		script++;3095	} else {3096		script = str;3097		ext = strrchr(script, '.');3098		if (!ext) {3099			fprintf(stderr, "invalid script extension");3100			return -1;3101		}3102		scripting_ops = script_spec__lookup(++ext);3103		if (!scripting_ops) {3104			fprintf(stderr, "invalid script extension");3105			return -1;3106		}3107	}3108 3109	script_name = find_script(script);3110	if (!script_name)3111		script_name = strdup(script);3112 3113	return 0;3114}3115 3116static int parse_output_fields(const struct option *opt __maybe_unused,3117			    const char *arg, int unset __maybe_unused)3118{3119	char *tok, *strtok_saveptr = NULL;3120	int i, imax = ARRAY_SIZE(all_output_options);3121	int j;3122	int rc = 0;3123	char *str = strdup(arg);3124	int type = -1;3125	enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;3126 3127	if (!str)3128		return -ENOMEM;3129 3130	/* first word can state for which event type the user is specifying3131	 * the fields. If no type exists, the specified fields apply to all3132	 * event types found in the file minus the invalid fields for a type.3133	 */3134	tok = strchr(str, ':');3135	if (tok) {3136		*tok = '\0';3137		tok++;3138		if (!strcmp(str, "hw"))3139			type = PERF_TYPE_HARDWARE;3140		else if (!strcmp(str, "sw"))3141			type = PERF_TYPE_SOFTWARE;3142		else if (!strcmp(str, "trace"))3143			type = PERF_TYPE_TRACEPOINT;3144		else if (!strcmp(str, "raw"))3145			type = PERF_TYPE_RAW;3146		else if (!strcmp(str, "break"))3147			type = PERF_TYPE_BREAKPOINT;3148		else if (!strcmp(str, "synth"))3149			type = OUTPUT_TYPE_SYNTH;3150		else {3151			fprintf(stderr, "Invalid event type in field string.\n");3152			rc = -EINVAL;3153			goto out;3154		}3155 3156		if (output[type].user_set)3157			pr_warning("Overriding previous field request for %s events.\n",3158				   event_type(type));3159 3160		/* Don't override defaults for +- */3161		if (strchr(tok, '+') || strchr(tok, '-'))3162			goto parse;3163 3164		output[type].fields = 0;3165		output[type].user_set = true;3166		output[type].wildcard_set = false;3167 3168	} else {3169		tok = str;3170		if (strlen(str) == 0) {3171			fprintf(stderr,3172				"Cannot set fields to 'none' for all event types.\n");3173			rc = -EINVAL;3174			goto out;3175		}3176 3177		/* Don't override defaults for +- */3178		if (strchr(str, '+') || strchr(str, '-'))3179			goto parse;3180 3181		if (output_set_by_user())3182			pr_warning("Overriding previous field request for all events.\n");3183 3184		for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {3185			output[j].fields = 0;3186			output[j].user_set = true;3187			output[j].wildcard_set = true;3188		}3189	}3190 3191parse:3192	for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {3193		if (*tok == '+') {3194			if (change == SET)3195				goto out_badmix;3196			change = ADD;3197			tok++;3198		} else if (*tok == '-') {3199			if (change == SET)3200				goto out_badmix;3201			change = REMOVE;3202			tok++;3203		} else {3204			if (change != SET && change != DEFAULT)3205				goto out_badmix;3206			change = SET;3207		}3208 3209		for (i = 0; i < imax; ++i) {3210			if (strcmp(tok, all_output_options[i].str) == 0)3211				break;3212		}3213		if (i == imax && strcmp(tok, "flags") == 0) {3214			print_flags = change != REMOVE;3215			continue;3216		}3217		if (i == imax) {3218			fprintf(stderr, "Invalid field requested.\n");3219			rc = -EINVAL;3220			goto out;3221		}3222#ifndef HAVE_LIBCAPSTONE_SUPPORT3223		if (change != REMOVE && strcmp(tok, "disasm") == 0) {3224			fprintf(stderr, "Field \"disasm\" requires perf to be built with libcapstone support.\n");3225			rc = -EINVAL;3226			goto out;3227		}3228#endif3229 3230		if (type == -1) {3231			/* add user option to all events types for3232			 * which it is valid3233			 */3234			for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {3235				if (output[j].invalid_fields & all_output_options[i].field) {3236					pr_warning("\'%s\' not valid for %s events. Ignoring.\n",3237						   all_output_options[i].str, event_type(j));3238				} else {3239					if (change == REMOVE) {3240						output[j].fields &= ~all_output_options[i].field;3241						output[j].user_set_fields &= ~all_output_options[i].field;3242						output[j].user_unset_fields |= all_output_options[i].field;3243					} else {3244						output[j].fields |= all_output_options[i].field;3245						output[j].user_set_fields |= all_output_options[i].field;3246						output[j].user_unset_fields &= ~all_output_options[i].field;3247					}3248					output[j].user_set = true;3249					output[j].wildcard_set = true;3250				}3251			}3252		} else {3253			if (output[type].invalid_fields & all_output_options[i].field) {3254				fprintf(stderr, "\'%s\' not valid for %s events.\n",3255					 all_output_options[i].str, event_type(type));3256 3257				rc = -EINVAL;3258				goto out;3259			}3260			if (change == REMOVE)3261				output[type].fields &= ~all_output_options[i].field;3262			else3263				output[type].fields |= all_output_options[i].field;3264			output[type].user_set = true;3265			output[type].wildcard_set = true;3266		}3267	}3268 3269	if (type >= 0) {3270		if (output[type].fields == 0) {3271			pr_debug("No fields requested for %s type. "3272				 "Events will not be displayed.\n", event_type(type));3273		}3274	}3275	goto out;3276 3277out_badmix:3278	fprintf(stderr, "Cannot mix +-field with overridden fields\n");3279	rc = -EINVAL;3280out:3281	free(str);3282	return rc;3283}3284 3285#define for_each_lang(scripts_path, scripts_dir, lang_dirent)		\3286	while ((lang_dirent = readdir(scripts_dir)) != NULL)		\3287		if ((lang_dirent->d_type == DT_DIR ||			\3288		     (lang_dirent->d_type == DT_UNKNOWN &&		\3289		      is_directory(scripts_path, lang_dirent))) &&	\3290		    (strcmp(lang_dirent->d_name, ".")) &&		\3291		    (strcmp(lang_dirent->d_name, "..")))3292 3293#define for_each_script(lang_path, lang_dir, script_dirent)		\3294	while ((script_dirent = readdir(lang_dir)) != NULL)		\3295		if (script_dirent->d_type != DT_DIR &&			\3296		    (script_dirent->d_type != DT_UNKNOWN ||		\3297		     !is_directory(lang_path, script_dirent)))3298 3299 3300#define RECORD_SUFFIX			"-record"3301#define REPORT_SUFFIX			"-report"3302 3303struct script_desc {3304	struct list_head	node;3305	char			*name;3306	char			*half_liner;3307	char			*args;3308};3309 3310static LIST_HEAD(script_descs);3311 3312static struct script_desc *script_desc__new(const char *name)3313{3314	struct script_desc *s = zalloc(sizeof(*s));3315 3316	if (s != NULL && name)3317		s->name = strdup(name);3318 3319	return s;3320}3321 3322static void script_desc__delete(struct script_desc *s)3323{3324	zfree(&s->name);3325	zfree(&s->half_liner);3326	zfree(&s->args);3327	free(s);3328}3329 3330static void script_desc__add(struct script_desc *s)3331{3332	list_add_tail(&s->node, &script_descs);3333}3334 3335static struct script_desc *script_desc__find(const char *name)3336{3337	struct script_desc *s;3338 3339	list_for_each_entry(s, &script_descs, node)3340		if (strcasecmp(s->name, name) == 0)3341			return s;3342	return NULL;3343}3344 3345static struct script_desc *script_desc__findnew(const char *name)3346{3347	struct script_desc *s = script_desc__find(name);3348 3349	if (s)3350		return s;3351 3352	s = script_desc__new(name);3353	if (!s)3354		return NULL;3355 3356	script_desc__add(s);3357 3358	return s;3359}3360 3361static const char *ends_with(const char *str, const char *suffix)3362{3363	size_t suffix_len = strlen(suffix);3364	const char *p = str;3365 3366	if (strlen(str) > suffix_len) {3367		p = str + strlen(str) - suffix_len;3368		if (!strncmp(p, suffix, suffix_len))3369			return p;3370	}3371 3372	return NULL;3373}3374 3375static int read_script_info(struct script_desc *desc, const char *filename)3376{3377	char line[BUFSIZ], *p;3378	FILE *fp;3379 3380	fp = fopen(filename, "r");3381	if (!fp)3382		return -1;3383 3384	while (fgets(line, sizeof(line), fp)) {3385		p = skip_spaces(line);3386		if (strlen(p) == 0)3387			continue;3388		if (*p != '#')3389			continue;3390		p++;3391		if (strlen(p) && *p == '!')3392			continue;3393 3394		p = skip_spaces(p);3395		if (strlen(p) && p[strlen(p) - 1] == '\n')3396			p[strlen(p) - 1] = '\0';3397 3398		if (!strncmp(p, "description:", strlen("description:"))) {3399			p += strlen("description:");3400			desc->half_liner = strdup(skip_spaces(p));3401			continue;3402		}3403 3404		if (!strncmp(p, "args:", strlen("args:"))) {3405			p += strlen("args:");3406			desc->args = strdup(skip_spaces(p));3407			continue;3408		}3409	}3410 3411	fclose(fp);3412 3413	return 0;3414}3415 3416static char *get_script_root(struct dirent *script_dirent, const char *suffix)3417{3418	char *script_root, *str;3419 3420	script_root = strdup(script_dirent->d_name);3421	if (!script_root)3422		return NULL;3423 3424	str = (char *)ends_with(script_root, suffix);3425	if (!str) {3426		free(script_root);3427		return NULL;3428	}3429 3430	*str = '\0';3431	return script_root;3432}3433 3434static int list_available_scripts(const struct option *opt __maybe_unused,3435				  const char *s __maybe_unused,3436				  int unset __maybe_unused)3437{3438	struct dirent *script_dirent, *lang_dirent;3439	char *buf, *scripts_path, *script_path, *lang_path, *first_half;3440	DIR *scripts_dir, *lang_dir;3441	struct script_desc *desc;3442	char *script_root;3443 3444	buf = malloc(3 * MAXPATHLEN + BUFSIZ);3445	if (!buf) {3446		pr_err("malloc failed\n");3447		exit(-1);3448	}3449	scripts_path = buf;3450	script_path = buf + MAXPATHLEN;3451	lang_path = buf + 2 * MAXPATHLEN;3452	first_half = buf + 3 * MAXPATHLEN;3453 3454	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());3455 3456	scripts_dir = opendir(scripts_path);3457	if (!scripts_dir) {3458		fprintf(stdout,3459			"open(%s) failed.\n"3460			"Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",3461			scripts_path);3462		free(buf);3463		exit(-1);3464	}3465 3466	for_each_lang(scripts_path, scripts_dir, lang_dirent) {3467		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,3468			  lang_dirent->d_name);3469		lang_dir = opendir(lang_path);3470		if (!lang_dir)3471			continue;3472 3473		for_each_script(lang_path, lang_dir, script_dirent) {3474			script_root = get_script_root(script_dirent, REPORT_SUFFIX);3475			if (script_root) {3476				desc = script_desc__findnew(script_root);3477				scnprintf(script_path, MAXPATHLEN, "%s/%s",3478					  lang_path, script_dirent->d_name);3479				read_script_info(desc, script_path);3480				free(script_root);3481			}3482		}3483	}3484 3485	fprintf(stdout, "List of available trace scripts:\n");3486	list_for_each_entry(desc, &script_descs, node) {3487		sprintf(first_half, "%s %s", desc->name,3488			desc->args ? desc->args : "");3489		fprintf(stdout, "  %-36s %s\n", first_half,3490			desc->half_liner ? desc->half_liner : "");3491	}3492 3493	free(buf);3494	exit(0);3495}3496 3497static int add_dlarg(const struct option *opt __maybe_unused,3498		     const char *s, int unset __maybe_unused)3499{3500	char *arg = strdup(s);3501	void *a;3502 3503	if (!arg)3504		return -1;3505 3506	a = realloc(dlargv, sizeof(dlargv[0]) * (dlargc + 1));3507	if (!a) {3508		free(arg);3509		return -1;3510	}3511 3512	dlargv = a;3513	dlargv[dlargc++] = arg;3514 3515	return 0;3516}3517 3518static void free_dlarg(void)3519{3520	while (dlargc--)3521		free(dlargv[dlargc]);3522	free(dlargv);3523}3524 3525/*3526 * Some scripts specify the required events in their "xxx-record" file,3527 * this function will check if the events in perf.data match those3528 * mentioned in the "xxx-record".3529 *3530 * Fixme: All existing "xxx-record" are all in good formats "-e event ",3531 * which is covered well now. And new parsing code should be added to3532 * cover the future complex formats like event groups etc.3533 */3534static int check_ev_match(char *dir_name, char *scriptname,3535			struct perf_session *session)3536{3537	char filename[MAXPATHLEN], evname[128];3538	char line[BUFSIZ], *p;3539	struct evsel *pos;3540	int match, len;3541	FILE *fp;3542 3543	scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname);3544 3545	fp = fopen(filename, "r");3546	if (!fp)3547		return -1;3548 3549	while (fgets(line, sizeof(line), fp)) {3550		p = skip_spaces(line);3551		if (*p == '#')3552			continue;3553 3554		while (strlen(p)) {3555			p = strstr(p, "-e");3556			if (!p)3557				break;3558 3559			p += 2;3560			p = skip_spaces(p);3561			len = strcspn(p, " \t");3562			if (!len)3563				break;3564 3565			snprintf(evname, len + 1, "%s", p);3566 3567			match = 0;3568			evlist__for_each_entry(session->evlist, pos) {3569				if (evsel__name_is(pos, evname)) {3570					match = 1;3571					break;3572				}3573			}3574 3575			if (!match) {3576				fclose(fp);3577				return -1;3578			}3579		}3580	}3581 3582	fclose(fp);3583	return 0;3584}3585 3586/*3587 * Return -1 if none is found, otherwise the actual scripts number.3588 *3589 * Currently the only user of this function is the script browser, which3590 * will list all statically runnable scripts, select one, execute it and3591 * show the output in a perf browser.3592 */3593int find_scripts(char **scripts_array, char **scripts_path_array, int num,3594		 int pathlen)3595{3596	struct dirent *script_dirent, *lang_dirent;3597	char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];3598	DIR *scripts_dir, *lang_dir;3599	struct perf_session *session;3600	struct perf_data data = {3601		.path = input_name,3602		.mode = PERF_DATA_MODE_READ,3603	};3604	char *temp;3605	int i = 0;3606 3607	session = perf_session__new(&data, NULL);3608	if (IS_ERR(session))3609		return PTR_ERR(session);3610 3611	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());3612 3613	scripts_dir = opendir(scripts_path);3614	if (!scripts_dir) {3615		perf_session__delete(session);3616		return -1;3617	}3618 3619	for_each_lang(scripts_path, scripts_dir, lang_dirent) {3620		scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,3621			  lang_dirent->d_name);3622#ifndef HAVE_LIBPERL_SUPPORT3623		if (strstr(lang_path, "perl"))3624			continue;3625#endif3626#ifndef HAVE_LIBPYTHON_SUPPORT3627		if (strstr(lang_path, "python"))3628			continue;3629#endif3630 3631		lang_dir = opendir(lang_path);3632		if (!lang_dir)3633			continue;3634 3635		for_each_script(lang_path, lang_dir, script_dirent) {3636			/* Skip those real time scripts: xxxtop.p[yl] */3637			if (strstr(script_dirent->d_name, "top."))3638				continue;3639			if (i >= num)3640				break;3641			snprintf(scripts_path_array[i], pathlen, "%s/%s",3642				lang_path,3643				script_dirent->d_name);3644			temp = strchr(script_dirent->d_name, '.');3645			snprintf(scripts_array[i],3646				(temp - script_dirent->d_name) + 1,3647				"%s", script_dirent->d_name);3648 3649			if (check_ev_match(lang_path,3650					scripts_array[i], session))3651				continue;3652 3653			i++;3654		}3655		closedir(lang_dir);3656	}3657 3658	closedir(scripts_dir);3659	perf_session__delete(session);3660	return i;3661}3662 3663static char *get_script_path(const char *script_root, const char *suffix)3664{3665	struct dirent *script_dirent, *lang_dirent;3666	char scripts_path[MAXPATHLEN];3667	char script_path[MAXPATHLEN];3668	DIR *scripts_dir, *lang_dir;3669	char lang_path[MAXPATHLEN];3670	char *__script_root;3671 3672	snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());3673 3674	scripts_dir = opendir(scripts_path);3675	if (!scripts_dir)3676		return NULL;3677 3678	for_each_lang(scripts_path, scripts_dir, lang_dirent) {3679		scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,3680			  lang_dirent->d_name);3681		lang_dir = opendir(lang_path);3682		if (!lang_dir)3683			continue;3684 3685		for_each_script(lang_path, lang_dir, script_dirent) {3686			__script_root = get_script_root(script_dirent, suffix);3687			if (__script_root && !strcmp(script_root, __script_root)) {3688				free(__script_root);3689				closedir(scripts_dir);3690				scnprintf(script_path, MAXPATHLEN, "%s/%s",3691					  lang_path, script_dirent->d_name);3692				closedir(lang_dir);3693				return strdup(script_path);3694			}3695			free(__script_root);3696		}3697		closedir(lang_dir);3698	}3699	closedir(scripts_dir);3700 3701	return NULL;3702}3703 3704static bool is_top_script(const char *script_path)3705{3706	return ends_with(script_path, "top") != NULL;3707}3708 3709static int has_required_arg(char *script_path)3710{3711	struct script_desc *desc;3712	int n_args = 0;3713	char *p;3714 3715	desc = script_desc__new(NULL);3716 3717	if (read_script_info(desc, script_path))3718		goto out;3719 3720	if (!desc->args)3721		goto out;3722 3723	for (p = desc->args; *p; p++)3724		if (*p == '<')3725			n_args++;3726out:3727	script_desc__delete(desc);3728 3729	return n_args;3730}3731 3732static int have_cmd(int argc, const char **argv)3733{3734	char **__argv = malloc(sizeof(const char *) * argc);3735 3736	if (!__argv) {3737		pr_err("malloc failed\n");3738		return -1;3739	}3740 3741	memcpy(__argv, argv, sizeof(const char *) * argc);3742	argc = parse_options(argc, (const char **)__argv, record_options,3743			     NULL, PARSE_OPT_STOP_AT_NON_OPTION);3744	free(__argv);3745 3746	system_wide = (argc == 0);3747 3748	return 0;3749}3750 3751static void script__setup_sample_type(struct perf_script *script)3752{3753	struct perf_session *session = script->session;3754	u64 sample_type = evlist__combined_sample_type(session->evlist);3755 3756	callchain_param_setup(sample_type, perf_env__arch(session->machines.host.env));3757 3758	if (script->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) {3759		pr_warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"3760			   "Please apply --call-graph lbr when recording.\n");3761		script->stitch_lbr = false;3762	}3763}3764 3765static int process_stat_round_event(struct perf_session *session,3766				    union perf_event *event)3767{3768	struct perf_record_stat_round *round = &event->stat_round;3769	struct evsel *counter;3770 3771	evlist__for_each_entry(session->evlist, counter) {3772		perf_stat_process_counter(&stat_config, counter);3773		process_stat(counter, round->time);3774	}3775 3776	process_stat_interval(round->time);3777	return 0;3778}3779 3780static int process_stat_config_event(struct perf_session *session __maybe_unused,3781				     union perf_event *event)3782{3783	perf_event__read_stat_config(&stat_config, &event->stat_config);3784 3785	/*3786	 * Aggregation modes are not used since post-processing scripts are3787	 * supposed to take care of such requirements3788	 */3789	stat_config.aggr_mode = AGGR_NONE;3790 3791	return 0;3792}3793 3794static int set_maps(struct perf_script *script)3795{3796	struct evlist *evlist = script->session->evlist;3797 3798	if (!script->cpus || !script->threads)3799		return 0;3800 3801	if (WARN_ONCE(script->allocated, "stats double allocation\n"))3802		return -EINVAL;3803 3804	perf_evlist__set_maps(&evlist->core, script->cpus, script->threads);3805 3806	if (evlist__alloc_stats(&stat_config, evlist, /*alloc_raw=*/true))3807		return -ENOMEM;3808 3809	script->allocated = true;3810	return 0;3811}3812 3813static3814int process_thread_map_event(struct perf_session *session,3815			     union perf_event *event)3816{3817	const struct perf_tool *tool = session->tool;3818	struct perf_script *script = container_of(tool, struct perf_script, tool);3819 3820	if (dump_trace)3821		perf_event__fprintf_thread_map(event, stdout);3822 3823	if (script->threads) {3824		pr_warning("Extra thread map event, ignoring.\n");3825		return 0;3826	}3827 3828	script->threads = thread_map__new_event(&event->thread_map);3829	if (!script->threads)3830		return -ENOMEM;3831 3832	return set_maps(script);3833}3834 3835static3836int process_cpu_map_event(struct perf_session *session,3837			  union perf_event *event)3838{3839	const struct perf_tool *tool = session->tool;3840	struct perf_script *script = container_of(tool, struct perf_script, tool);3841 3842	if (dump_trace)3843		perf_event__fprintf_cpu_map(event, stdout);3844 3845	if (script->cpus) {3846		pr_warning("Extra cpu map event, ignoring.\n");3847		return 0;3848	}3849 3850	script->cpus = cpu_map__new_data(&event->cpu_map.data);3851	if (!script->cpus)3852		return -ENOMEM;3853 3854	return set_maps(script);3855}3856 3857static int process_feature_event(struct perf_session *session,3858				 union perf_event *event)3859{3860	if (event->feat.feat_id < HEADER_LAST_FEATURE)3861		return perf_event__process_feature(session, event);3862	return 0;3863}3864 3865#ifdef HAVE_AUXTRACE_SUPPORT3866static int perf_script__process_auxtrace_info(struct perf_session *session,3867					      union perf_event *event)3868{3869	int ret = perf_event__process_auxtrace_info(session, event);3870 3871	if (ret == 0) {3872		const struct perf_tool *tool = session->tool;3873		struct perf_script *script = container_of(tool, struct perf_script, tool);3874 3875		ret = perf_script__setup_per_event_dump(script);3876	}3877 3878	return ret;3879}3880#else3881#define perf_script__process_auxtrace_info 03882#endif3883 3884static int parse_insn_trace(const struct option *opt __maybe_unused,3885			    const char *str, int unset __maybe_unused)3886{3887	const char *fields = "+insn,-event,-period";3888	int ret;3889 3890	if (str) {3891		if (strcmp(str, "disasm") == 0)3892			fields = "+disasm,-event,-period";3893		else if (strlen(str) != 0 && strcmp(str, "raw") != 0) {3894			fprintf(stderr, "Only accept raw|disasm\n");3895			return -EINVAL;3896		}3897	}3898 3899	ret = parse_output_fields(NULL, fields, 0);3900	if (ret < 0)3901		return ret;3902 3903	itrace_parse_synth_opts(opt, "i0nse", 0);3904	symbol_conf.nanosecs = true;3905	return 0;3906}3907 3908static int parse_xed(const struct option *opt __maybe_unused,3909		     const char *str __maybe_unused,3910		     int unset __maybe_unused)3911{3912	if (isatty(1))3913		force_pager("xed -F insn: -A -64 | less");3914	else3915		force_pager("xed -F insn: -A -64");3916	return 0;3917}3918 3919static int parse_call_trace(const struct option *opt __maybe_unused,3920			    const char *str __maybe_unused,3921			    int unset __maybe_unused)3922{3923	parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent", 0);3924	itrace_parse_synth_opts(opt, "cewp", 0);3925	symbol_conf.nanosecs = true;3926	symbol_conf.pad_output_len_dso = 50;3927	return 0;3928}3929 3930static int parse_callret_trace(const struct option *opt __maybe_unused,3931			    const char *str __maybe_unused,3932			    int unset __maybe_unused)3933{3934	parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent,+flags", 0);3935	itrace_parse_synth_opts(opt, "crewp", 0);3936	symbol_conf.nanosecs = true;3937	return 0;3938}3939 3940int cmd_script(int argc, const char **argv)3941{3942	bool show_full_info = false;3943	bool header = false;3944	bool header_only = false;3945	bool script_started = false;3946	bool unsorted_dump = false;3947	char *rec_script_path = NULL;3948	char *rep_script_path = NULL;3949	struct perf_session *session;3950	struct itrace_synth_opts itrace_synth_opts = {3951		.set = false,3952		.default_no_sample = true,3953	};3954	struct utsname uts;3955	char *script_path = NULL;3956	const char *dlfilter_file = NULL;3957	const char **__argv;3958	int i, j, err = 0;3959	struct perf_script script = {};3960	struct perf_data data = {3961		.mode = PERF_DATA_MODE_READ,3962	};3963	const struct option options[] = {3964	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,3965		    "dump raw trace in ASCII"),3966	OPT_BOOLEAN(0, "dump-unsorted-raw-trace", &unsorted_dump,3967		    "dump unsorted raw trace in ASCII"),3968	OPT_INCR('v', "verbose", &verbose,3969		 "be more verbose (show symbol address, etc)"),3970	OPT_BOOLEAN('L', "Latency", &latency_format,3971		    "show latency attributes (irqs/preemption disabled, etc)"),3972	OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",3973			   list_available_scripts),3974	OPT_CALLBACK_NOOPT(0, "list-dlfilters", NULL, NULL, "list available dlfilters",3975			   list_available_dlfilters),3976	OPT_CALLBACK('s', "script", NULL, "name",3977		     "script file name (lang:script name, script name, or *)",3978		     parse_scriptname),3979	OPT_STRING('g', "gen-script", &generate_script_lang, "lang",3980		   "generate perf-script.xx script in specified language"),3981	OPT_STRING(0, "dlfilter", &dlfilter_file, "file", "filter .so file name"),3982	OPT_CALLBACK(0, "dlarg", NULL, "argument", "filter argument",3983		     add_dlarg),3984	OPT_STRING('i', "input", &input_name, "file", "input file name"),3985	OPT_BOOLEAN('d', "debug-mode", &debug_mode,3986		   "do various checks like samples ordering and lost events"),3987	OPT_BOOLEAN(0, "header", &header, "Show data header."),3988	OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),3989	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,3990		   "file", "vmlinux pathname"),3991	OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,3992		   "file", "kallsyms pathname"),3993	OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,3994		    "When printing symbols do not display call chain"),3995	OPT_CALLBACK(0, "symfs", NULL, "directory",3996		     "Look for files with symbols relative to this directory",3997		     symbol__config_symfs),3998	OPT_CALLBACK('F', "fields", NULL, "str",3999		     "comma separated output fields prepend with 'type:'. "4000		     "+field to add and -field to remove."4001		     "Valid types: hw,sw,trace,raw,synth. "4002		     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,dsoff,"4003		     "addr,symoff,srcline,period,iregs,uregs,brstack,"4004		     "brstacksym,flags,data_src,weight,bpf-output,brstackinsn,"4005		     "brstackinsnlen,brstackdisasm,brstackoff,callindent,insn,disasm,insnlen,synth,"4006		     "phys_addr,metric,misc,srccode,ipc,tod,data_page_size,"4007		     "code_page_size,ins_lat,machine_pid,vcpu,cgroup,retire_lat,"4008		     "brcntr",4009		     parse_output_fields),4010	OPT_BOOLEAN('a', "all-cpus", &system_wide,4011		    "system-wide collection from all CPUs"),4012	OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",4013		   "only consider symbols in these DSOs"),4014	OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",4015		   "only consider these symbols"),4016	OPT_INTEGER(0, "addr-range", &symbol_conf.addr_range,4017		    "Use with -S to list traced records within address range"),4018	OPT_CALLBACK_OPTARG(0, "insn-trace", &itrace_synth_opts, NULL, "raw|disasm",4019			"Decode instructions from itrace", parse_insn_trace),4020	OPT_CALLBACK_OPTARG(0, "xed", NULL, NULL, NULL,4021			"Run xed disassembler on output", parse_xed),4022	OPT_CALLBACK_OPTARG(0, "call-trace", &itrace_synth_opts, NULL, NULL,4023			"Decode calls from itrace", parse_call_trace),4024	OPT_CALLBACK_OPTARG(0, "call-ret-trace", &itrace_synth_opts, NULL, NULL,4025			"Decode calls and returns from itrace", parse_callret_trace),4026	OPT_STRING(0, "graph-function", &symbol_conf.graph_function, "symbol[,symbol...]",4027			"Only print symbols and callees with --call-trace/--call-ret-trace"),4028	OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]",4029		   "Stop display of callgraph at these symbols"),4030	OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),4031	OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",4032		   "only display events for these comms"),4033	OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",4034		   "only consider symbols in these pids"),4035	OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",4036		   "only consider symbols in these tids"),4037	OPT_UINTEGER(0, "max-stack", &scripting_max_stack,4038		     "Set the maximum stack depth when parsing the callchain, "4039		     "anything beyond the specified depth will be ignored. "4040		     "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),4041	OPT_BOOLEAN(0, "reltime", &reltime, "Show time stamps relative to start"),4042	OPT_BOOLEAN(0, "deltatime", &deltatime, "Show time stamps relative to previous event"),4043	OPT_BOOLEAN('I', "show-info", &show_full_info,4044		    "display extended information from perf.data file"),4045	OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,4046		    "Show the path of [kernel.kallsyms]"),4047	OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events,4048		    "Show the fork/comm/exit events"),4049	OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,4050		    "Show the mmap events"),4051	OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,4052		    "Show context switch events (if recorded)"),4053	OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,4054		    "Show namespace events (if recorded)"),4055	OPT_BOOLEAN('\0', "show-cgroup-events", &script.show_cgroup_events,4056		    "Show cgroup events (if recorded)"),4057	OPT_BOOLEAN('\0', "show-lost-events", &script.show_lost_events,4058		    "Show lost events (if recorded)"),4059	OPT_BOOLEAN('\0', "show-round-events", &script.show_round_events,4060		    "Show round events (if recorded)"),4061	OPT_BOOLEAN('\0', "show-bpf-events", &script.show_bpf_events,4062		    "Show bpf related events (if recorded)"),4063	OPT_BOOLEAN('\0', "show-text-poke-events", &script.show_text_poke_events,4064		    "Show text poke related events (if recorded)"),4065	OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,4066		    "Dump trace output to files named by the monitored events"),4067	OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),4068	OPT_INTEGER(0, "max-blocks", &max_blocks,4069		    "Maximum number of code blocks to dump with brstackinsn"),4070	OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs,4071		    "Use 9 decimal places when displaying time"),4072	OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",4073			    "Instruction Tracing options\n" ITRACE_HELP,4074			    itrace_parse_synth_opts),4075	OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,4076			"Show full source file name path for source lines"),4077	OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,4078			"Enable symbol demangling"),4079	OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,4080			"Enable kernel symbol demangling"),4081	OPT_STRING(0, "addr2line", &symbol_conf.addr2line_path, "path",4082			"addr2line binary to use for line numbers"),4083	OPT_STRING(0, "time", &script.time_str, "str",4084		   "Time span of interest (start,stop)"),4085	OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,4086		    "Show inline function"),4087	OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory",4088		   "guest mount directory under which every guest os"4089		   " instance has a subdir"),4090	OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name,4091		   "file", "file saving guest os vmlinux"),4092	OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms,4093		   "file", "file saving guest os /proc/kallsyms"),4094	OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,4095		   "file", "file saving guest os /proc/modules"),4096	OPT_BOOLEAN(0, "guest-code", &symbol_conf.guest_code,4097		    "Guest code can be found in hypervisor process"),4098	OPT_BOOLEAN('\0', "stitch-lbr", &script.stitch_lbr,4099		    "Enable LBR callgraph stitching approach"),4100	OPTS_EVSWITCH(&script.evswitch),4101	OPT_END()4102	};4103	const char * const script_subcommands[] = { "record", "report", NULL };4104	const char *script_usage[] = {4105		"perf script [<options>]",4106		"perf script [<options>] record <script> [<record-options>] <command>",4107		"perf script [<options>] report <script> [script-args]",4108		"perf script [<options>] <script> [<record-options>] <command>",4109		"perf script [<options>] <top-script> [script-args]",4110		NULL4111	};4112 4113	perf_set_singlethreaded();4114 4115	setup_scripting();4116 4117	argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,4118			     PARSE_OPT_STOP_AT_NON_OPTION);4119 4120	if (symbol_conf.guestmount ||4121	    symbol_conf.default_guest_vmlinux_name ||4122	    symbol_conf.default_guest_kallsyms ||4123	    symbol_conf.default_guest_modules ||4124	    symbol_conf.guest_code) {4125		/*4126		 * Enable guest sample processing.4127		 */4128		perf_guest = true;4129	}4130 4131	data.path  = input_name;4132	data.force = symbol_conf.force;4133 4134	if (unsorted_dump)4135		dump_trace = true;4136 4137	if (symbol__validate_sym_arguments())4138		return -1;4139 4140	if (argc > 1 && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {4141		rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);4142		if (!rec_script_path)4143			return cmd_record(argc, argv);4144	}4145 4146	if (argc > 1 && strlen(argv[0]) > 2 && strstarts("report", argv[0])) {4147		rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);4148		if (!rep_script_path) {4149			fprintf(stderr,4150				"Please specify a valid report script"4151				"(see 'perf script -l' for listing)\n");4152			return -1;4153		}4154	}4155 4156	if (reltime && deltatime) {4157		fprintf(stderr,4158			"reltime and deltatime - the two don't get along well. "4159			"Please limit to --reltime or --deltatime.\n");4160		return -1;4161	}4162 4163	if ((itrace_synth_opts.callchain || itrace_synth_opts.add_callchain) &&4164	    itrace_synth_opts.callchain_sz > scripting_max_stack)4165		scripting_max_stack = itrace_synth_opts.callchain_sz;4166 4167	/* make sure PERF_EXEC_PATH is set for scripts */4168	set_argv_exec_path(get_argv_exec_path());4169 4170	if (argc && !script_name && !rec_script_path && !rep_script_path) {4171		int live_pipe[2];4172		int rep_args;4173		pid_t pid;4174 4175		rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);4176		rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);4177 4178		if (!rec_script_path && !rep_script_path) {4179			script_name = find_script(argv[0]);4180			if (script_name) {4181				argc -= 1;4182				argv += 1;4183				goto script_found;4184			}4185			usage_with_options_msg(script_usage, options,4186				"Couldn't find script `%s'\n\n See perf"4187				" script -l for available scripts.\n", argv[0]);4188		}4189 4190		if (is_top_script(argv[0])) {4191			rep_args = argc - 1;4192		} else {4193			int rec_args;4194 4195			rep_args = has_required_arg(rep_script_path);4196			rec_args = (argc - 1) - rep_args;4197			if (rec_args < 0) {4198				usage_with_options_msg(script_usage, options,4199					"`%s' script requires options."4200					"\n\n See perf script -l for available "4201					"scripts and options.\n", argv[0]);4202			}4203		}4204 4205		if (pipe(live_pipe) < 0) {4206			perror("failed to create pipe");4207			return -1;4208		}4209 4210		pid = fork();4211		if (pid < 0) {4212			perror("failed to fork");4213			return -1;4214		}4215 4216		if (!pid) {4217			j = 0;4218 4219			dup2(live_pipe[1], 1);4220			close(live_pipe[0]);4221 4222			if (is_top_script(argv[0])) {4223				system_wide = true;4224			} else if (!system_wide) {4225				if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {4226					err = -1;4227					goto out;4228				}4229			}4230 4231			__argv = malloc((argc + 6) * sizeof(const char *));4232			if (!__argv) {4233				pr_err("malloc failed\n");4234				err = -ENOMEM;4235				goto out;4236			}4237 4238			__argv[j++] = "/bin/sh";4239			__argv[j++] = rec_script_path;4240			if (system_wide)4241				__argv[j++] = "-a";4242			__argv[j++] = "-q";4243			__argv[j++] = "-o";4244			__argv[j++] = "-";4245			for (i = rep_args + 1; i < argc; i++)4246				__argv[j++] = argv[i];4247			__argv[j++] = NULL;4248 4249			execvp("/bin/sh", (char **)__argv);4250			free(__argv);4251			exit(-1);4252		}4253 4254		dup2(live_pipe[0], 0);4255		close(live_pipe[1]);4256 4257		__argv = malloc((argc + 4) * sizeof(const char *));4258		if (!__argv) {4259			pr_err("malloc failed\n");4260			err = -ENOMEM;4261			goto out;4262		}4263 4264		j = 0;4265		__argv[j++] = "/bin/sh";4266		__argv[j++] = rep_script_path;4267		for (i = 1; i < rep_args + 1; i++)4268			__argv[j++] = argv[i];4269		__argv[j++] = "-i";4270		__argv[j++] = "-";4271		__argv[j++] = NULL;4272 4273		execvp("/bin/sh", (char **)__argv);4274		free(__argv);4275		exit(-1);4276	}4277script_found:4278	if (rec_script_path)4279		script_path = rec_script_path;4280	if (rep_script_path)4281		script_path = rep_script_path;4282 4283	if (script_path) {4284		j = 0;4285 4286		if (!rec_script_path)4287			system_wide = false;4288		else if (!system_wide) {4289			if (have_cmd(argc - 1, &argv[1]) != 0) {4290				err = -1;4291				goto out;4292			}4293		}4294 4295		__argv = malloc((argc + 2) * sizeof(const char *));4296		if (!__argv) {4297			pr_err("malloc failed\n");4298			err = -ENOMEM;4299			goto out;4300		}4301 4302		__argv[j++] = "/bin/sh";4303		__argv[j++] = script_path;4304		if (system_wide)4305			__argv[j++] = "-a";4306		for (i = 2; i < argc; i++)4307			__argv[j++] = argv[i];4308		__argv[j++] = NULL;4309 4310		execvp("/bin/sh", (char **)__argv);4311		free(__argv);4312		exit(-1);4313	}4314 4315	if (dlfilter_file) {4316		dlfilter = dlfilter__new(dlfilter_file, dlargc, dlargv);4317		if (!dlfilter)4318			return -1;4319	}4320 4321	if (!script_name) {4322		setup_pager();4323		use_browser = 0;4324	}4325 4326	perf_tool__init(&script.tool, !unsorted_dump);4327	script.tool.sample		 = process_sample_event;4328	script.tool.mmap		 = perf_event__process_mmap;4329	script.tool.mmap2		 = perf_event__process_mmap2;4330	script.tool.comm		 = perf_event__process_comm;4331	script.tool.namespaces		 = perf_event__process_namespaces;4332	script.tool.cgroup		 = perf_event__process_cgroup;4333	script.tool.exit		 = perf_event__process_exit;4334	script.tool.fork		 = perf_event__process_fork;4335	script.tool.attr		 = process_attr;4336	script.tool.event_update	 = perf_event__process_event_update;4337#ifdef HAVE_LIBTRACEEVENT4338	script.tool.tracing_data	 = perf_event__process_tracing_data;4339#endif4340	script.tool.feature		 = process_feature_event;4341	script.tool.build_id		 = perf_event__process_build_id;4342	script.tool.id_index		 = perf_event__process_id_index;4343	script.tool.auxtrace_info	 = perf_script__process_auxtrace_info;4344	script.tool.auxtrace		 = perf_event__process_auxtrace;4345	script.tool.auxtrace_error	 = perf_event__process_auxtrace_error;4346	script.tool.stat		 = perf_event__process_stat_event;4347	script.tool.stat_round		 = process_stat_round_event;4348	script.tool.stat_config		 = process_stat_config_event;4349	script.tool.thread_map		 = process_thread_map_event;4350	script.tool.cpu_map		 = process_cpu_map_event;4351	script.tool.throttle		 = process_throttle_event;4352	script.tool.unthrottle		 = process_throttle_event;4353	script.tool.ordering_requires_timestamps = true;4354	session = perf_session__new(&data, &script.tool);4355	if (IS_ERR(session))4356		return PTR_ERR(session);4357 4358	if (header || header_only) {4359		script.tool.show_feat_hdr = SHOW_FEAT_HEADER;4360		perf_session__fprintf_info(session, stdout, show_full_info);4361		if (header_only)4362			goto out_delete;4363	}4364	if (show_full_info)4365		script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;4366 4367	if (symbol__init(&session->header.env) < 0)4368		goto out_delete;4369 4370	uname(&uts);4371	if (data.is_pipe) { /* Assume pipe_mode indicates native_arch */4372		native_arch = true;4373	} else if (session->header.env.arch) {4374		if (!strcmp(uts.machine, session->header.env.arch))4375			native_arch = true;4376		else if (!strcmp(uts.machine, "x86_64") &&4377			 !strcmp(session->header.env.arch, "i386"))4378			native_arch = true;4379	}4380 4381	script.session = session;4382	script__setup_sample_type(&script);4383 4384	if ((output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT) ||4385	    symbol_conf.graph_function)4386		itrace_synth_opts.thread_stack = true;4387 4388	session->itrace_synth_opts = &itrace_synth_opts;4389 4390	if (cpu_list) {4391		err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);4392		if (err < 0)4393			goto out_delete;4394		itrace_synth_opts.cpu_bitmap = cpu_bitmap;4395	}4396 4397	if (!no_callchain)4398		symbol_conf.use_callchain = true;4399	else4400		symbol_conf.use_callchain = false;4401 4402#ifdef HAVE_LIBTRACEEVENT4403	if (session->tevent.pevent &&4404	    tep_set_function_resolver(session->tevent.pevent,4405				      machine__resolve_kernel_addr,4406				      &session->machines.host) < 0) {4407		pr_err("%s: failed to set libtraceevent function resolver\n", __func__);4408		err = -1;4409		goto out_delete;4410	}4411#endif4412	if (generate_script_lang) {4413		struct stat perf_stat;4414		int input;4415 4416		if (output_set_by_user()) {4417			fprintf(stderr,4418				"custom fields not supported for generated scripts");4419			err = -EINVAL;4420			goto out_delete;4421		}4422 4423		input = open(data.path, O_RDONLY);	/* input_name */4424		if (input < 0) {4425			err = -errno;4426			perror("failed to open file");4427			goto out_delete;4428		}4429 4430		err = fstat(input, &perf_stat);4431		if (err < 0) {4432			perror("failed to stat file");4433			goto out_delete;4434		}4435 4436		if (!perf_stat.st_size) {4437			fprintf(stderr, "zero-sized file, nothing to do!\n");4438			goto out_delete;4439		}4440 4441		scripting_ops = script_spec__lookup(generate_script_lang);4442		if (!scripting_ops) {4443			fprintf(stderr, "invalid language specifier");4444			err = -ENOENT;4445			goto out_delete;4446		}4447#ifdef HAVE_LIBTRACEEVENT4448		err = scripting_ops->generate_script(session->tevent.pevent,4449						     "perf-script");4450#else4451		err = scripting_ops->generate_script(NULL, "perf-script");4452#endif4453		goto out_delete;4454	}4455 4456	err = dlfilter__start(dlfilter, session);4457	if (err)4458		goto out_delete;4459 4460	if (script_name) {4461		err = scripting_ops->start_script(script_name, argc, argv, session);4462		if (err)4463			goto out_delete;4464		pr_debug("perf script started with script %s\n\n", script_name);4465		script_started = true;4466	}4467 4468 4469	err = perf_session__check_output_opt(session);4470	if (err < 0)4471		goto out_delete;4472 4473	if (script.time_str) {4474		err = perf_time__parse_for_ranges_reltime(script.time_str, session,4475						  &script.ptime_range,4476						  &script.range_size,4477						  &script.range_num,4478						  reltime);4479		if (err < 0)4480			goto out_delete;4481 4482		itrace_synth_opts__set_time_range(&itrace_synth_opts,4483						  script.ptime_range,4484						  script.range_num);4485	}4486 4487	err = evswitch__init(&script.evswitch, session->evlist, stderr);4488	if (err)4489		goto out_delete;4490 4491	if (zstd_init(&(session->zstd_data), 0) < 0)4492		pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");4493 4494	err = __cmd_script(&script);4495 4496	flush_scripting();4497 4498	if (verbose > 2 || debug_kmaps)4499		perf_session__dump_kmaps(session);4500 4501out_delete:4502	if (script.ptime_range) {4503		itrace_synth_opts__clear_time_range(&itrace_synth_opts);4504		zfree(&script.ptime_range);4505	}4506 4507	zstd_fini(&(session->zstd_data));4508	evlist__free_stats(session->evlist);4509	perf_session__delete(session);4510	perf_script__exit(&script);4511 4512	if (script_started)4513		cleanup_scripting();4514	dlfilter__cleanup(dlfilter);4515	free_dlarg();4516out:4517	return err;4518}4519