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