]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - tools/perf/builtin-script.c
Linux 6.16-rc4
[thirdparty/kernel/stable.git] / tools / perf / builtin-script.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
5f9c39dc
FW
2#include "builtin.h"
3
0f31c019 4#include "util/counts.h"
b7eead86 5#include "util/debug.h"
4a3cec84 6#include "util/dso.h"
4b6ab94e 7#include <subcmd/exec-cmd.h>
b7eead86 8#include "util/header.h"
4b6ab94e 9#include <subcmd/parse-options.h>
fc36f948 10#include "util/perf_regs.h"
b7eead86 11#include "util/session.h"
45694aa7 12#include "util/tool.h"
1101f69a 13#include "util/map.h"
97b9d866 14#include "util/srcline.h"
5f9c39dc
FW
15#include "util/symbol.h"
16#include "util/thread.h"
cf72344d 17#include "util/trace-event.h"
83869019 18#include "util/env.h"
1424dc96
DA
19#include "util/evlist.h"
20#include "util/evsel.h"
ca125277 21#include "util/evsel_fprintf.h"
d2360442 22#include "util/evswitch.h"
36385be5 23#include "util/sort.h"
f5fc1412 24#include "util/data.h"
7a680eb9 25#include "util/auxtrace.h"
cfc8874a
JO
26#include "util/cpumap.h"
27#include "util/thread_map.h"
28#include "util/stat.h"
4bd1bef8 29#include "util/color.h"
a067558e 30#include "util/string2.h"
e216708d 31#include "util/thread-stack.h"
a91f4c47 32#include "util/time-utils.h"
06c3f2aa 33#include "util/path.h"
6b9bae63 34#include "util/event.h"
ad3003a6 35#include "util/mem-info.h"
fa0d9846 36#include "ui/ui.h"
fea01392 37#include "print_binary.h"
8f0ec15f 38#include "print_insn.h"
3ab481a1 39#include "archinsn.h"
5d67be97 40#include <linux/bitmap.h>
877a7a11 41#include <linux/kernel.h>
6125cc8d 42#include <linux/stringify.h>
bd48c63e 43#include <linux/time64.h>
7f7c536f 44#include <linux/zalloc.h>
3ab481a1 45#include <sys/utsname.h>
cfc8874a 46#include "asm/bug.h"
c19ac912 47#include "util/mem-events.h"
48d02a1d 48#include "util/dump-insn.h"
76b31a29 49#include <dirent.h>
a43783ae 50#include <errno.h>
fd20e811 51#include <inttypes.h>
9607ad3a 52#include <signal.h>
391e4206 53#include <sys/param.h>
7a8ef4c4
ACM
54#include <sys/types.h>
55#include <sys/stat.h>
bafae98e 56#include <fcntl.h>
7a8ef4c4 57#include <unistd.h>
b585ebdb 58#include <subcmd/pager.h>
453fa030 59#include <perf/evlist.h>
6ef81c55 60#include <linux/err.h>
291961fc 61#include "util/dlfilter.h"
aeb00b1a 62#include "util/record.h"
2da39f1c 63#include "util/util.h"
3fd7a168 64#include "util/cgroup.h"
6f9d8d1d 65#include "util/annotate.h"
c1a604df 66#include "perf.h"
5f9c39dc 67
3052ba56 68#include <linux/ctype.h>
378ef0f5 69#ifdef HAVE_LIBTRACEEVENT
35de42cd 70#include <event-parse.h>
378ef0f5 71#endif
3d689ed6 72
956ffd02
TZ
73static char const *script_name;
74static char const *generate_script_lang;
90b10f47 75static bool reltime;
26567ed7 76static bool deltatime;
90b10f47 77static u64 initial_time;
26567ed7 78static u64 previous_time;
ffabd99e 79static bool debug_mode;
e1889d75 80static u64 last_timestamp;
6fcf7ddb 81static u64 nr_unordered;
c0230b2b 82static bool no_callchain;
47390ae2 83static bool latency_format;
317df650 84static bool system_wide;
400ea6d3 85static bool print_flags;
5d67be97
AB
86static const char *cpu_list;
87static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
48d02a1d 88static int max_blocks;
3ab481a1 89static bool native_arch;
291961fc 90static struct dlfilter *dlfilter;
3d032a25
AH
91static int dlargc;
92static char **dlargv;
956ffd02 93
745f43e3 94enum perf_output_field {
60e5eeb5
JO
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,
e534bfb1 127 PERF_OUTPUT_TOD = 1ULL << 32,
6b9bae63 128 PERF_OUTPUT_DATA_PAGE_SIZE = 1ULL << 33,
c513de8a 129 PERF_OUTPUT_CODE_PAGE_SIZE = 1ULL << 34,
6ea5d1a3 130 PERF_OUTPUT_INS_LAT = 1ULL << 35,
6f680c6a 131 PERF_OUTPUT_BRSTACKINSNLEN = 1ULL << 36,
e28fb159
AH
132 PERF_OUTPUT_MACHINE_PID = 1ULL << 37,
133 PERF_OUTPUT_VCPU = 1ULL << 38,
3fd7a168 134 PERF_OUTPUT_CGROUP = 1ULL << 39,
17f248aa 135 PERF_OUTPUT_RETIRE_LAT = 1ULL << 40,
af9eb56b 136 PERF_OUTPUT_DSOFF = 1ULL << 41,
99417234 137 PERF_OUTPUT_DISASM = 1ULL << 42,
d8120446 138 PERF_OUTPUT_BRSTACKDISASM = 1ULL << 43,
6f9d8d1d 139 PERF_OUTPUT_BRCNTR = 1ULL << 44,
e534bfb1
JO
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;
745f43e3
DA
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},
787bef17 178 {.str = "ip", .field = PERF_OUTPUT_IP},
c0230b2b 179 {.str = "sym", .field = PERF_OUTPUT_SYM},
610723f2 180 {.str = "dso", .field = PERF_OUTPUT_DSO},
af9eb56b 181 {.str = "dsoff", .field = PERF_OUTPUT_DSOFF},
7cec0922 182 {.str = "addr", .field = PERF_OUTPUT_ADDR},
a978f2ab 183 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
cc8fae1d 184 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
535aeaae 185 {.str = "period", .field = PERF_OUTPUT_PERIOD},
fc36f948 186 {.str = "iregs", .field = PERF_OUTPUT_IREGS},
b1491ace 187 {.str = "uregs", .field = PERF_OUTPUT_UREGS},
dc323ce8
SE
188 {.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
189 {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
94ddddfa
JO
190 {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},
191 {.str = "weight", .field = PERF_OUTPUT_WEIGHT},
30372f04 192 {.str = "bpf-output", .field = PERF_OUTPUT_BPF_OUTPUT},
e216708d 193 {.str = "callindent", .field = PERF_OUTPUT_CALLINDENT},
224e2c97 194 {.str = "insn", .field = PERF_OUTPUT_INSN},
99417234 195 {.str = "disasm", .field = PERF_OUTPUT_DISASM},
224e2c97 196 {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},
48d02a1d 197 {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
106dacd8 198 {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
47e78084 199 {.str = "synth", .field = PERF_OUTPUT_SYNTH},
49d58f04 200 {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
4bd1bef8 201 {.str = "metric", .field = PERF_OUTPUT_METRIC},
28a0b398 202 {.str = "misc", .field = PERF_OUTPUT_MISC},
dd2e18e9 203 {.str = "srccode", .field = PERF_OUTPUT_SRCCODE},
68fb45bf 204 {.str = "ipc", .field = PERF_OUTPUT_IPC},
e534bfb1 205 {.str = "tod", .field = PERF_OUTPUT_TOD},
6b9bae63 206 {.str = "data_page_size", .field = PERF_OUTPUT_DATA_PAGE_SIZE},
c513de8a 207 {.str = "code_page_size", .field = PERF_OUTPUT_CODE_PAGE_SIZE},
6ea5d1a3 208 {.str = "ins_lat", .field = PERF_OUTPUT_INS_LAT},
6f680c6a 209 {.str = "brstackinsnlen", .field = PERF_OUTPUT_BRSTACKINSNLEN},
e28fb159
AH
210 {.str = "machine_pid", .field = PERF_OUTPUT_MACHINE_PID},
211 {.str = "vcpu", .field = PERF_OUTPUT_VCPU},
3fd7a168 212 {.str = "cgroup", .field = PERF_OUTPUT_CGROUP},
17f248aa 213 {.str = "retire_lat", .field = PERF_OUTPUT_RETIRE_LAT},
d8120446 214 {.str = "brstackdisasm", .field = PERF_OUTPUT_BRSTACKDISASM},
6f9d8d1d 215 {.str = "brcntr", .field = PERF_OUTPUT_BRCNTR},
745f43e3
DA
216};
217
1405720d
AH
218enum {
219 OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,
8adc0a06 220 OUTPUT_TYPE_OTHER,
1405720d
AH
221 OUTPUT_TYPE_MAX
222};
223
efff5add
ACM
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
745f43e3 228/* default set to maintain compatibility with current format */
2c9e45f7
DA
229static struct {
230 bool user_set;
9cbdb702 231 bool wildcard_set;
a6ffaf91 232 unsigned int print_ip_opts;
2c9e45f7
DA
233 u64 fields;
234 u64 invalid_fields;
4b6ac811 235 u64 user_set_fields;
b5164085 236 u64 user_unset_fields;
1405720d 237} output[OUTPUT_TYPE_MAX] = {
2c9e45f7
DA
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 |
787bef17 244 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
7903a708
SD
245 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
246 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
2c9e45f7 247
30372f04 248 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
2c9e45f7
DA
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 |
787bef17 256 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
7903a708
SD
257 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
258 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
259 PERF_OUTPUT_BPF_OUTPUT,
2c9e45f7
DA
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 |
30372f04 269 PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE
2c9e45f7 270 },
0817a6a3 271
fad76d43
ST
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
0817a6a3
AS
284 [PERF_TYPE_RAW] = {
285 .user_set = false,
286
287 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
288 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
787bef17 289 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
7903a708
SD
290 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
291 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD |
292 PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC |
6b9bae63 293 PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR |
6ea5d1a3 294 PERF_OUTPUT_DATA_PAGE_SIZE | PERF_OUTPUT_CODE_PAGE_SIZE |
17f248aa 295 PERF_OUTPUT_INS_LAT | PERF_OUTPUT_RETIRE_LAT,
0817a6a3 296
30372f04 297 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
0817a6a3 298 },
27cfef00
WN
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 |
7903a708
SD
306 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
307 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
27cfef00 308
30372f04 309 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
27cfef00 310 },
1405720d
AH
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 |
7903a708
SD
318 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
319 PERF_OUTPUT_DSO | PERF_OUTPUT_SYNTH,
1405720d
AH
320
321 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
322 },
8adc0a06
JY
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 },
1424dc96 335};
745f43e3 336
32dcd021 337struct evsel_script {
642ee1c6
ACM
338 char *filename;
339 FILE *fp;
340 u64 samples;
4bd1bef8
AK
341 /* For metric output */
342 u64 val;
343 int gnum;
642ee1c6
ACM
344};
345
32dcd021 346static inline struct evsel_script *evsel_script(struct evsel *evsel)
4bd1bef8 347{
32dcd021 348 return (struct evsel_script *)evsel->priv;
4bd1bef8
AK
349}
350
297e69bf 351static struct evsel_script *evsel_script__new(struct evsel *evsel, struct perf_data *data)
642ee1c6 352{
32dcd021 353 struct evsel_script *es = zalloc(sizeof(*es));
642ee1c6
ACM
354
355 if (es != NULL) {
8ab2e96d 356 if (asprintf(&es->filename, "%s.%s.dump", data->file.path, evsel__name(evsel)) < 0)
642ee1c6
ACM
357 goto out_free;
358 es->fp = fopen(es->filename, "w");
359 if (es->fp == NULL)
360 goto out_free_filename;
642ee1c6
ACM
361 }
362
363 return es;
364out_free_filename:
365 zfree(&es->filename);
366out_free:
367 free(es);
368 return NULL;
369}
370
297e69bf 371static void evsel_script__delete(struct evsel_script *es)
642ee1c6
ACM
372{
373 zfree(&es->filename);
374 fclose(es->fp);
375 es->fp = NULL;
376 free(es);
377}
378
297e69bf 379static int evsel_script__fprintf(struct evsel_script *es, FILE *fp)
642ee1c6
ACM
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
1405720d
AH
388static inline int output_type(unsigned int type)
389{
390 switch (type) {
391 case PERF_TYPE_SYNTH:
392 return OUTPUT_TYPE_SYNTH;
393 default:
8adc0a06
JY
394 if (type < PERF_TYPE_MAX)
395 return type;
1405720d 396 }
8adc0a06
JY
397
398 return OUTPUT_TYPE_OTHER;
1405720d
AH
399}
400
efff5add
ACM
401static inline int evsel__output_type(struct evsel *evsel)
402{
74fb903b 403 int type = evsel->script_output_type;
efff5add 404
74fb903b
TF
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;
efff5add
ACM
417}
418
2c9e45f7
DA
419static bool output_set_by_user(void)
420{
421 int j;
1405720d 422 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2c9e45f7
DA
423 if (output[j].user_set)
424 return true;
425 }
426 return false;
427}
745f43e3 428
9cbdb702
DA
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
efff5add 443#define PRINT_FIELD(x) (output[evsel__output_type(evsel)].fields & PERF_OUTPUT_##x)
1424dc96 444
ec98b6df
ACM
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)
1424dc96 447{
1fc632ce 448 struct perf_event_attr *attr = &evsel->core.attr;
efff5add 449 int type = evsel__output_type(evsel);
9cbdb702
DA
450 const char *evname;
451
452 if (attr->sample_type & sample_type)
453 return 0;
454
4b6ac811 455 if (output[type].user_set_fields & field) {
6d5cdd64
AH
456 if (allow_user_set)
457 return 0;
8ab2e96d 458 evname = evsel__name(evsel);
9cbdb702
DA
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;
8ab2e96d 467 evname = evsel__name(evsel);
9cbdb702
DA
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
ec98b6df
ACM
475static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
476 enum perf_output_field field)
6d5cdd64 477{
ec98b6df 478 return evsel__do_check_stype(evsel, sample_type, sample_msg, field, false);
6d5cdd64
AH
479}
480
afdd63f5 481static int evsel__check_attr(struct evsel *evsel, struct perf_session *session)
9cbdb702 482{
6d5cdd64
AH
483 bool allow_user_set;
484
82b2425f
ZX
485 if (evsel__is_dummy_event(evsel))
486 return 0;
487
e099eba8
JO
488 if (perf_header__has_feat(&session->header, HEADER_STAT))
489 return 0;
490
6d5cdd64
AH
491 allow_user_set = perf_header__has_feat(&session->header,
492 HEADER_AUXTRACE);
9cbdb702 493
1424dc96 494 if (PRINT_FIELD(TRACE) &&
ec98b6df 495 !perf_session__has_traces(session, "record -R"))
1424dc96
DA
496 return -EINVAL;
497
787bef17 498 if (PRINT_FIELD(IP)) {
ec98b6df 499 if (evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", PERF_OUTPUT_IP))
1424dc96 500 return -EINVAL;
1424dc96 501 }
7cec0922
DA
502
503 if (PRINT_FIELD(ADDR) &&
ec98b6df 504 evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", PERF_OUTPUT_ADDR, allow_user_set))
7cec0922
DA
505 return -EINVAL;
506
94ddddfa 507 if (PRINT_FIELD(DATA_SRC) &&
c6d8df01 508 evsel__do_check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC", PERF_OUTPUT_DATA_SRC, allow_user_set))
94ddddfa
JO
509 return -EINVAL;
510
511 if (PRINT_FIELD(WEIGHT) &&
13e741b8 512 evsel__do_check_stype(evsel, PERF_SAMPLE_WEIGHT_TYPE, "WEIGHT", PERF_OUTPUT_WEIGHT, allow_user_set))
94ddddfa
JO
513 return -EINVAL;
514
37fed3de 515 if (PRINT_FIELD(SYM) &&
ec98b6df 516 !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
7cec0922 517 pr_err("Display of symbols requested but neither sample IP nor "
37fed3de 518 "sample address\navailable. Hence, no addresses to convert "
7cec0922 519 "to symbols.\n");
787bef17
DA
520 return -EINVAL;
521 }
a978f2ab
AN
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 }
37fed3de 527 if (PRINT_FIELD(DSO) &&
ec98b6df 528 !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
37fed3de 529 pr_err("Display of DSO requested but no address to convert.\n");
610723f2
DA
530 return -EINVAL;
531 }
dd2e18e9 532 if ((PRINT_FIELD(SRCLINE) || PRINT_FIELD(SRCCODE)) && !PRINT_FIELD(IP)) {
cc8fae1d
AH
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 }
d8120446
AK
537 if ((PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN) || PRINT_FIELD(BRSTACKDISASM))
538 && !allow_user_set &&
92c7d7cd 539 !(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY)) {
48d02a1d
AK
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 }
6f9d8d1d
KL
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 }
1424dc96 550 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
ec98b6df 551 evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", PERF_OUTPUT_TID|PERF_OUTPUT_PID))
1424dc96 552 return -EINVAL;
1424dc96
DA
553
554 if (PRINT_FIELD(TIME) &&
ec98b6df 555 evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", PERF_OUTPUT_TIME))
1424dc96 556 return -EINVAL;
1424dc96
DA
557
558 if (PRINT_FIELD(CPU) &&
ec98b6df 559 evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU", PERF_OUTPUT_CPU, allow_user_set))
1424dc96 560 return -EINVAL;
9cbdb702 561
fc36f948 562 if (PRINT_FIELD(IREGS) &&
add07ccd 563 evsel__do_check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", PERF_OUTPUT_IREGS, allow_user_set))
fc36f948
SE
564 return -EINVAL;
565
b1491ace 566 if (PRINT_FIELD(UREGS) &&
ec98b6df 567 evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS", PERF_OUTPUT_UREGS))
b1491ace
AK
568 return -EINVAL;
569
49d58f04 570 if (PRINT_FIELD(PHYS_ADDR) &&
9edcde68 571 evsel__do_check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", PERF_OUTPUT_PHYS_ADDR, allow_user_set))
49d58f04
KL
572 return -EINVAL;
573
6b9bae63
KL
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
c513de8a
SE
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
6ea5d1a3
KL
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
3fd7a168
NK
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
17f248aa
KL
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
9cbdb702
DA
596 return 0;
597}
598
efff5add 599static void evsel__set_print_ip_opts(struct evsel *evsel)
7ea95727 600{
efff5add 601 unsigned int type = evsel__output_type(evsel);
7ea95727
AH
602
603 output[type].print_ip_opts = 0;
604 if (PRINT_FIELD(IP))
e20ab86e 605 output[type].print_ip_opts |= EVSEL__PRINT_IP;
7ea95727
AH
606
607 if (PRINT_FIELD(SYM))
e20ab86e 608 output[type].print_ip_opts |= EVSEL__PRINT_SYM;
7ea95727
AH
609
610 if (PRINT_FIELD(DSO))
e20ab86e 611 output[type].print_ip_opts |= EVSEL__PRINT_DSO;
7ea95727 612
af9eb56b
CD
613 if (PRINT_FIELD(DSOFF))
614 output[type].print_ip_opts |= EVSEL__PRINT_DSOFF;
615
7ea95727 616 if (PRINT_FIELD(SYMOFFSET))
e20ab86e 617 output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET;
cc8fae1d
AH
618
619 if (PRINT_FIELD(SRCLINE))
e20ab86e 620 output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
7ea95727
AH
621}
622
ff6f41fb
AH
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) {
35503ce1
JO
629 if (evsel__is_dummy_event(evsel))
630 continue;
efff5add 631 if (evsel__output_type(evsel) == (int)type)
ff6f41fb
AH
632 return evsel;
633 }
634 return NULL;
635}
636
9cbdb702
DA
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{
e534bfb1 643 bool tod = false;
40f20e50 644 unsigned int j;
32dcd021 645 struct evsel *evsel;
9cbdb702 646
1405720d 647 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
ff6f41fb 648 evsel = find_first_output_type(session->evlist, j);
9cbdb702
DA
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 */
1405720d
AH
654 if (!evsel && output[j].user_set && !output[j].wildcard_set &&
655 j != OUTPUT_TYPE_SYNTH) {
9cbdb702 656 pr_err("%s events do not exist. "
701516ae 657 "Remove corresponding -F option to proceed.\n",
9cbdb702
DA
658 event_type(j));
659 return -1;
660 }
661
662 if (evsel && output[j].fields &&
afdd63f5 663 evsel__check_attr(evsel, session))
9cbdb702 664 return -1;
a6ffaf91
DA
665
666 if (evsel == NULL)
667 continue;
668
af9eb56b
CD
669 /* 'dsoff' implys 'dso' field */
670 if (output[j].fields & PERF_OUTPUT_DSOFF)
671 output[j].fields |= PERF_OUTPUT_DSO;
672
efff5add 673 evsel__set_print_ip_opts(evsel);
e534bfb1 674 tod |= output[j].fields & PERF_OUTPUT_TOD;
1424dc96
DA
675 }
676
98526ee7
AH
677 if (!no_callchain) {
678 bool use_callchain = false;
71ac899b 679 bool not_pipe = false;
98526ee7 680
e5cadb93 681 evlist__for_each_entry(session->evlist, evsel) {
71ac899b 682 not_pipe = true;
8ae7a576 683 if (evsel__has_callchain(evsel) || evsel__is_offcpu_event(evsel)) {
98526ee7
AH
684 use_callchain = true;
685 break;
686 }
687 }
71ac899b 688 if (not_pipe && !use_callchain)
98526ee7
AH
689 symbol_conf.use_callchain = false;
690 }
691
80b8b496
DA
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) {
80b8b496 698 j = PERF_TYPE_TRACEPOINT;
80b8b496 699
e5cadb93 700 evlist__for_each_entry(session->evlist, evsel) {
1fc632ce 701 if (evsel->core.attr.type != j)
40f20e50
HK
702 continue;
703
27de9b2b 704 if (evsel__has_callchain(evsel)) {
40f20e50
HK
705 output[j].fields |= PERF_OUTPUT_IP;
706 output[j].fields |= PERF_OUTPUT_SYM;
7903a708 707 output[j].fields |= PERF_OUTPUT_SYMOFFSET;
40f20e50 708 output[j].fields |= PERF_OUTPUT_DSO;
efff5add 709 evsel__set_print_ip_opts(evsel);
40f20e50
HK
710 goto out;
711 }
80b8b496
DA
712 }
713 }
714
e534bfb1
JO
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 }
80b8b496 720out:
1424dc96
DA
721 return 0;
722}
745f43e3 723
83869019 724static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, const char *arch,
e534bfb1 725 FILE *fp)
b1491ace 726{
b1491ace 727 unsigned i = 0, r;
a1a58707 728 int printed = 0;
b1491ace
AK
729
730 if (!regs || !regs->regs)
a1a58707 731 return 0;
b1491ace 732
a1a58707 733 printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi);
b1491ace
AK
734
735 for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
736 u64 val = regs->regs[i++];
83869019 737 printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r, arch), val);
b1491ace 738 }
a1a58707
ACM
739
740 return printed;
b1491ace
AK
741}
742
e534bfb1
JO
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
9add8fe8 793static int perf_sample__fprintf_iregs(struct perf_sample *sample,
83869019 794 struct perf_event_attr *attr, const char *arch, FILE *fp)
9add8fe8 795{
dc6d2bc2
IR
796 if (!sample->intr_regs)
797 return 0;
798
799 return perf_sample__fprintf_regs(perf_sample__intr_regs(sample),
83869019 800 attr->sample_regs_intr, arch, fp);
9add8fe8
MW
801}
802
803static int perf_sample__fprintf_uregs(struct perf_sample *sample,
83869019 804 struct perf_event_attr *attr, const char *arch, FILE *fp)
9add8fe8 805{
dc6d2bc2
IR
806 if (!sample->user_regs)
807 return 0;
808
809 return perf_sample__fprintf_regs(perf_sample__user_regs(sample),
83869019 810 attr->sample_regs_user, arch, fp);
9add8fe8
MW
811}
812
e534bfb1
JO
813static int perf_sample__fprintf_start(struct perf_script *script,
814 struct perf_sample *sample,
a1a58707 815 struct thread *thread,
32dcd021 816 struct evsel *evsel,
28a0b398 817 u32 type, FILE *fp)
c70c94b4 818{
c70c94b4 819 unsigned long secs;
745f43e3 820 unsigned long long nsecs;
a1a58707 821 int printed = 0;
e534bfb1 822 char tstr[128];
745f43e3 823
6f9d8d1d
KL
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
e28fb159
AH
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
745f43e3 844 if (PRINT_FIELD(COMM)) {
fc18380f
AH
845 const char *comm = thread ? thread__comm_str(thread) : ":-1";
846
745f43e3 847 if (latency_format)
fc18380f 848 printed += fprintf(fp, "%8.8s ", comm);
b879833c 849 else if (PRINT_FIELD(IP) && evsel__has_callchain(evsel) && symbol_conf.use_callchain)
fc18380f 850 printed += fprintf(fp, "%s ", comm);
745f43e3 851 else
fc18380f 852 printed += fprintf(fp, "%16s ", comm);
745f43e3 853 }
c70c94b4 854
745f43e3 855 if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
fe8e0434 856 printed += fprintf(fp, "%7d/%-7d ", sample->pid, sample->tid);
745f43e3 857 else if (PRINT_FIELD(PID))
fe8e0434 858 printed += fprintf(fp, "%7d ", sample->pid);
745f43e3 859 else if (PRINT_FIELD(TID))
fe8e0434 860 printed += fprintf(fp, "%7d ", sample->tid);
745f43e3
DA
861
862 if (PRINT_FIELD(CPU)) {
863 if (latency_format)
a1a58707 864 printed += fprintf(fp, "%3d ", sample->cpu);
745f43e3 865 else
a1a58707 866 printed += fprintf(fp, "[%03d] ", sample->cpu);
745f43e3 867 }
c70c94b4 868
28a0b398
JO
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:
bf30cc18 898 if (has(SWITCH_OUT)) {
28a0b398 899 ret += fprintf(fp, "S");
bf30cc18
AB
900 if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT)
901 ret += fprintf(fp, "p");
902 }
28a0b398
JO
903 default:
904 break;
905 }
906
907 #undef has
908
909 ret += fprintf(fp, "%*s", 6 - ret, " ");
910 printed += ret;
911 }
912
e534bfb1
JO
913 if (PRINT_FIELD(TOD)) {
914 tod_scnprintf(script, tstr, sizeof(tstr), sample->time);
915 printed += fprintf(fp, "%s ", tstr);
916 }
917
745f43e3 918 if (PRINT_FIELD(TIME)) {
90b10f47
AK
919 u64 t = sample->time;
920 if (reltime) {
921 if (!initial_time)
922 initial_time = sample->time;
923 t = sample->time - initial_time;
26567ed7
HPP
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;
90b10f47
AK
931 }
932 nsecs = t;
bd48c63e
ACM
933 secs = nsecs / NSEC_PER_SEC;
934 nsecs -= secs * NSEC_PER_SEC;
99620a5d 935
52bab886 936 if (symbol_conf.nanosecs)
a1a58707 937 printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs);
99620a5d
NK
938 else {
939 char sample_time[32];
90b10f47 940 timestamp__scnprintf_usec(t, sample_time, sizeof(sample_time));
a1a58707 941 printed += fprintf(fp, "%12s: ", sample_time);
99620a5d 942 }
745f43e3 943 }
a1a58707
ACM
944
945 return printed;
c70c94b4
DA
946}
947
1e66dcff
LY
948static inline size_t
949bstack_event_str(struct branch_entry *br, char *buf, size_t sz)
dc323ce8 950{
1e66dcff
LY
951 if (!(br->flags.mispred || br->flags.predicted || br->flags.not_taken))
952 return snprintf(buf, sz, "-");
dc323ce8 953
1e66dcff
LY
954 return snprintf(buf, sz, "%s%s",
955 br->flags.predicted ? "P" : "M",
956 br->flags.not_taken ? "N" : "");
dc323ce8
SE
957}
958
b2dac688
JC
959static int print_bstack_flags(FILE *fp, struct branch_entry *br)
960{
1e66dcff
LY
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,
b2dac688
JC
967 br->flags.in_tx ? 'X' : '-',
968 br->flags.abort ? 'A' : '-',
1f48989c 969 br->flags.cycles,
6ade6c64
SD
970 get_branch_type(br),
971 br->flags.spec ? branch_spec_desc(br->flags.spec) : "-");
b2dac688
JC
972}
973
a1a58707
ACM
974static int perf_sample__fprintf_brstack(struct perf_sample *sample,
975 struct thread *thread,
efff5add 976 struct evsel *evsel, FILE *fp)
dc323ce8
SE
977{
978 struct branch_stack *br = sample->branch_stack;
42bbabed 979 struct branch_entry *entries = perf_sample__branch_entries(sample);
55b9b508 980 u64 i, from, to;
a1a58707 981 int printed = 0;
dc323ce8
SE
982
983 if (!(br && br->nr))
a1a58707 984 return 0;
dc323ce8
SE
985
986 for (i = 0; i < br->nr; i++) {
42bbabed
KL
987 from = entries[i].from;
988 to = entries[i].to;
55b9b508 989
0dd5041c 990 printed += fprintf(fp, " 0x%"PRIx64, from);
55b9b508 991 if (PRINT_FIELD(DSO)) {
0dd5041c
IR
992 struct addr_location alf, alt;
993
994 addr_location__init(&alf);
995 addr_location__init(&alt);
692d0e63
AH
996 thread__find_map_fb(thread, sample->cpumode, from, &alf);
997 thread__find_map_fb(thread, sample->cpumode, to, &alt);
55b9b508 998
af9eb56b 999 printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);
0dd5041c 1000 printed += fprintf(fp, "/0x%"PRIx64, to);
af9eb56b 1001 printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);
0dd5041c
IR
1002 addr_location__exit(&alt);
1003 addr_location__exit(&alf);
1004 } else
1005 printed += fprintf(fp, "/0x%"PRIx64, to);
55b9b508 1006
b2dac688 1007 printed += print_bstack_flags(fp, entries + i);
dc323ce8 1008 }
a1a58707
ACM
1009
1010 return printed;
dc323ce8
SE
1011}
1012
a1a58707
ACM
1013static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
1014 struct thread *thread,
efff5add 1015 struct evsel *evsel, FILE *fp)
dc323ce8
SE
1016{
1017 struct branch_stack *br = sample->branch_stack;
42bbabed 1018 struct branch_entry *entries = perf_sample__branch_entries(sample);
dc323ce8 1019 u64 i, from, to;
a1a58707 1020 int printed = 0;
dc323ce8
SE
1021
1022 if (!(br && br->nr))
a1a58707 1023 return 0;
dc323ce8
SE
1024
1025 for (i = 0; i < br->nr; i++) {
0dd5041c 1026 struct addr_location alf, alt;
dc323ce8 1027
0dd5041c
IR
1028 addr_location__init(&alf);
1029 addr_location__init(&alt);
42bbabed
KL
1030 from = entries[i].from;
1031 to = entries[i].to;
dc323ce8 1032
692d0e63
AH
1033 thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
1034 thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
dc323ce8 1035
a1a58707 1036 printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
af9eb56b
CD
1037 if (PRINT_FIELD(DSO))
1038 printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);
a1a58707
ACM
1039 printed += fprintf(fp, "%c", '/');
1040 printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp);
af9eb56b
CD
1041 if (PRINT_FIELD(DSO))
1042 printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);
b2dac688 1043 printed += print_bstack_flags(fp, entries + i);
0dd5041c
IR
1044 addr_location__exit(&alt);
1045 addr_location__exit(&alf);
dc323ce8 1046 }
a1a58707
ACM
1047
1048 return printed;
dc323ce8
SE
1049}
1050
a1a58707
ACM
1051static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
1052 struct thread *thread,
efff5add 1053 struct evsel *evsel, FILE *fp)
106dacd8
MS
1054{
1055 struct branch_stack *br = sample->branch_stack;
42bbabed 1056 struct branch_entry *entries = perf_sample__branch_entries(sample);
106dacd8 1057 u64 i, from, to;
a1a58707 1058 int printed = 0;
106dacd8
MS
1059
1060 if (!(br && br->nr))
a1a58707 1061 return 0;
106dacd8
MS
1062
1063 for (i = 0; i < br->nr; i++) {
0dd5041c 1064 struct addr_location alf, alt;
106dacd8 1065
0dd5041c
IR
1066 addr_location__init(&alf);
1067 addr_location__init(&alt);
42bbabed
KL
1068 from = entries[i].from;
1069 to = entries[i].to;
106dacd8 1070
692d0e63 1071 if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
ee756ef7 1072 !dso__adjust_symbols(map__dso(alf.map)))
0e6aa013 1073 from = map__dso_map_ip(alf.map, from);
106dacd8 1074
692d0e63 1075 if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
ee756ef7 1076 !dso__adjust_symbols(map__dso(alt.map)))
0e6aa013 1077 to = map__dso_map_ip(alt.map, to);
106dacd8 1078
a1a58707 1079 printed += fprintf(fp, " 0x%"PRIx64, from);
af9eb56b
CD
1080 if (PRINT_FIELD(DSO))
1081 printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp);
a1a58707 1082 printed += fprintf(fp, "/0x%"PRIx64, to);
af9eb56b
CD
1083 if (PRINT_FIELD(DSO))
1084 printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp);
b2dac688 1085 printed += print_bstack_flags(fp, entries + i);
0dd5041c
IR
1086 addr_location__exit(&alt);
1087 addr_location__exit(&alf);
106dacd8 1088 }
a1a58707
ACM
1089
1090 return printed;
106dacd8 1091}
48d02a1d
AK
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;
63df0e4b 1101 struct dso *dso;
0dd5041c 1102 int ret = 0;
48d02a1d
AK
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)) {
5ce2c5b4 1120 pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end);
48d02a1d
AK
1121 return -ENXIO;
1122 }
1123
48d02a1d
AK
1124 if (end - start > MAXBB - MAXINSN) {
1125 if (last)
5ce2c5b4 1126 pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end);
48d02a1d 1127 else
5ce2c5b4 1128 pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start);
48d02a1d
AK
1129 return 0;
1130 }
1131
0dd5041c 1132 addr_location__init(&al);
3ad1be6f 1133 if (!thread__find_map(thread, *cpumode, start, &al) || (dso = map__dso(al.map)) == NULL) {
5ce2c5b4 1134 pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
0dd5041c 1135 goto out;
48d02a1d 1136 }
ee756ef7 1137 if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR) {
5ce2c5b4 1138 pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
0dd5041c 1139 goto out;
48d02a1d
AK
1140 }
1141
1142 /* Load maps to ensure dso->is_64_bit has been updated */
1143 map__load(al.map);
1144
78a1f7cd 1145 offset = map__map_ip(al.map, start);
63df0e4b 1146 len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer,
48d02a1d
AK
1147 end - start + MAXINSN);
1148
ee756ef7 1149 *is64bit = dso__is_64_bit(dso);
48d02a1d 1150 if (len <= 0)
5ce2c5b4 1151 pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
48d02a1d 1152 start, end);
0dd5041c
IR
1153 ret = len;
1154out:
1155 addr_location__exit(&al);
1156 return ret;
48d02a1d
AK
1157}
1158
540a63ea
ACM
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;
3ad1be6f 1166 struct dso *dso;
540a63ea 1167
3ad1be6f 1168 if (!map || (dso = map__dso(map)) == NULL)
540a63ea 1169 return 0;
63df0e4b 1170 srcfile = get_srcline_split(dso,
540a63ea
ACM
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
dd2e18e9
AK
1202static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr)
1203{
1204 struct addr_location al;
1205 int ret = 0;
1206
0dd5041c 1207 addr_location__init(&al);
dd2e18e9
AK
1208 thread__find_map(thread, cpumode, addr, &al);
1209 if (!al.map)
0dd5041c 1210 goto out;
dd2e18e9 1211 ret = map__fprintf_srccode(al.map, al.addr, stdout,
ee84a303 1212 thread__srccode_state(thread));
dd2e18e9
AK
1213 if (ret)
1214 ret += printf("\n");
0dd5041c
IR
1215out:
1216 addr_location__exit(&al);
dd2e18e9
AK
1217 return ret;
1218}
1219
efff5add 1220static int any_dump_insn(struct evsel *evsel __maybe_unused,
218c200f
AH
1221 struct perf_insn *x, uint64_t ip,
1222 u8 *inbuf, int inlen, int *lenp,
1223 FILE *fp)
d8120446
AK
1224{
1225#ifdef HAVE_LIBCAPSTONE_SUPPORT
1226 if (PRINT_FIELD(BRSTACKDISASM)) {
218c200f
AH
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;
d8120446
AK
1233 }
1234#endif
218c200f
AH
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;
d8120446
AK
1243}
1244
a1a58707
ACM
1245static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
1246 struct perf_insn *x, u8 *inbuf, int len,
6f680c6a 1247 int insn, FILE *fp, int *total_cycles,
6f9d8d1d 1248 struct evsel *evsel,
efff5add 1249 struct thread *thread,
6f9d8d1d 1250 u64 br_cntr)
48d02a1d 1251{
6f680c6a 1252 int ilen = 0;
218c200f
AH
1253 int printed = fprintf(fp, "\t%016" PRIx64 "\t", ip);
1254
efff5add 1255 printed += add_padding(fp, any_dump_insn(evsel, x, ip, inbuf, len, &ilen, fp), 30);
218c200f 1256 printed += fprintf(fp, "\t");
6f680c6a
KL
1257
1258 if (PRINT_FIELD(BRSTACKINSNLEN))
1259 printed += fprintf(fp, "ilen: %d\t", ilen);
1260
112c5547
KL
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
6f9d8d1d 1271 if (PRINT_FIELD(BRCNTR)) {
6f9d8d1d 1272 struct evsel *pos = evsel__leader(evsel);
edf3ce0e 1273 unsigned int i = 0, j, num, mask, width;
6f9d8d1d 1274
edf3ce0e
KL
1275 perf_env__find_br_cntr_info(evsel__env(evsel), NULL, &width);
1276 mask = (1L << width) - 1;
6f9d8d1d
KL
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
6f680c6a 1294 printed += fprintf(fp, "#%s%s%s%s",
a1a58707
ACM
1295 en->flags.predicted ? " PRED" : "",
1296 en->flags.mispred ? " MISPRED" : "",
1297 en->flags.in_tx ? " INTX" : "",
1298 en->flags.abort ? " ABORT" : "");
48d02a1d 1299 if (en->flags.cycles) {
fe57120e
AK
1300 *total_cycles += en->flags.cycles;
1301 printed += fprintf(fp, " %d cycles [%d]", en->flags.cycles, *total_cycles);
48d02a1d 1302 if (insn)
a1a58707 1303 printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
48d02a1d 1304 }
112c5547 1305
a1a58707 1306 return printed + fprintf(fp, "\n");
48d02a1d
AK
1307}
1308
a1a58707
ACM
1309static int ip__fprintf_sym(uint64_t addr, struct thread *thread,
1310 u8 cpumode, int cpu, struct symbol **lastsym,
efff5add 1311 struct evsel *evsel, FILE *fp)
48d02a1d
AK
1312{
1313 struct addr_location al;
0dd5041c 1314 int off, printed = 0, ret = 0;
48d02a1d 1315
0dd5041c 1316 addr_location__init(&al);
404eb5a4
ACM
1317 thread__find_map(thread, cpumode, addr, &al);
1318
48d02a1d 1319 if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
0dd5041c 1320 goto out;
48d02a1d
AK
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)
0dd5041c 1328 goto out;
48d02a1d
AK
1329
1330 if (al.addr < al.sym->end)
1331 off = al.addr - al.sym->start;
1332 else
e5116f46 1333 off = al.addr - map__start(al.map) - al.sym->start;
a1a58707 1334 printed += fprintf(fp, "\t%s", al.sym->name);
48d02a1d 1335 if (off)
a1a58707
ACM
1336 printed += fprintf(fp, "%+d", off);
1337 printed += fprintf(fp, ":");
48d02a1d 1338 if (PRINT_FIELD(SRCLINE))
a1a58707
ACM
1339 printed += map__fprintf_srcline(al.map, al.addr, "\t", fp);
1340 printed += fprintf(fp, "\n");
48d02a1d 1341 *lastsym = al.sym;
a1a58707 1342
0dd5041c
IR
1343 ret = printed;
1344out:
1345 addr_location__exit(&al);
1346 return ret;
48d02a1d
AK
1347}
1348
a1a58707 1349static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
6f9d8d1d 1350 struct evsel *evsel,
a1a58707
ACM
1351 struct thread *thread,
1352 struct perf_event_attr *attr,
1353 struct machine *machine, FILE *fp)
48d02a1d
AK
1354{
1355 struct branch_stack *br = sample->branch_stack;
42bbabed 1356 struct branch_entry *entries = perf_sample__branch_entries(sample);
48d02a1d 1357 u64 start, end;
a1a58707 1358 int i, insn, len, nr, ilen, printed = 0;
48d02a1d
AK
1359 struct perf_insn x;
1360 u8 buffer[MAXBB];
1361 unsigned off;
1362 struct symbol *lastsym = NULL;
fe57120e 1363 int total_cycles = 0;
6f9d8d1d 1364 u64 br_cntr = 0;
48d02a1d
AK
1365
1366 if (!(br && br->nr))
a1a58707 1367 return 0;
48d02a1d
AK
1368 nr = br->nr;
1369 if (max_blocks && nr > max_blocks + 1)
1370 nr = max_blocks + 1;
1371
1372 x.thread = thread;
d8120446 1373 x.machine = machine;
48d02a1d
AK
1374 x.cpu = sample->cpu;
1375
6f9d8d1d
KL
1376 if (PRINT_FIELD(BRCNTR) && sample->branch_stack_cntr)
1377 br_cntr = sample->branch_stack_cntr[nr - 1];
1378
a1a58707 1379 printed += fprintf(fp, "%c", '\n');
48d02a1d
AK
1380
1381 /* Handle first from jump, of which we don't know the entry. */
42bbabed
KL
1382 len = grab_bb(buffer, entries[nr-1].from,
1383 entries[nr-1].from,
48d02a1d
AK
1384 machine, thread, &x.is64bit, &x.cpumode, false);
1385 if (len > 0) {
42bbabed 1386 printed += ip__fprintf_sym(entries[nr - 1].from, thread,
efff5add 1387 x.cpumode, x.cpu, &lastsym, evsel, fp);
42bbabed 1388 printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1],
6f680c6a 1389 &x, buffer, len, 0, fp, &total_cycles,
efff5add 1390 evsel, thread, br_cntr);
dd2e18e9 1391 if (PRINT_FIELD(SRCCODE))
42bbabed 1392 printed += print_srccode(thread, x.cpumode, entries[nr - 1].from);
48d02a1d
AK
1393 }
1394
1395 /* Print all blocks */
1396 for (i = nr - 2; i >= 0; i--) {
42bbabed 1397 if (entries[i].from || entries[i].to)
48d02a1d 1398 pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i,
42bbabed
KL
1399 entries[i].from,
1400 entries[i].to);
1401 start = entries[i + 1].to;
1402 end = entries[i].from;
48d02a1d
AK
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) {
42bbabed 1407 end = entries[--i].from;
48d02a1d
AK
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;
e98df280 1415 for (off = 0; off < (unsigned)len; off += ilen) {
48d02a1d
AK
1416 uint64_t ip = start + off;
1417
efff5add 1418 printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, evsel, fp);
48d02a1d 1419 if (ip == end) {
6f9d8d1d
KL
1420 if (PRINT_FIELD(BRCNTR) && sample->branch_stack_cntr)
1421 br_cntr = sample->branch_stack_cntr[i];
42bbabed 1422 printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp,
efff5add 1423 &total_cycles, evsel, thread, br_cntr);
dd2e18e9
AK
1424 if (PRINT_FIELD(SRCCODE))
1425 printed += print_srccode(thread, x.cpumode, ip);
48d02a1d
AK
1426 break;
1427 } else {
e98df280 1428 ilen = 0;
218c200f 1429 printed += fprintf(fp, "\t%016" PRIx64 "\t", ip);
efff5add 1430 printed += any_dump_insn(evsel, &x, ip, buffer + off, len - off, &ilen, fp);
6f680c6a
KL
1431 if (PRINT_FIELD(BRSTACKINSNLEN))
1432 printed += fprintf(fp, "\tilen: %d", ilen);
1433 printed += fprintf(fp, "\n");
48d02a1d
AK
1434 if (ilen == 0)
1435 break;
dd2e18e9
AK
1436 if (PRINT_FIELD(SRCCODE))
1437 print_srccode(thread, x.cpumode, ip);
48d02a1d
AK
1438 insn++;
1439 }
1440 }
5172672d 1441 if (off != end - start)
e98df280 1442 printed += fprintf(fp, "\tmismatch of LBR data and executable\n");
48d02a1d
AK
1443 }
1444
1445 /*
1446 * Hit the branch? In this case we are already done, and the target
1447 * has not been executed yet.
1448 */
42bbabed 1449 if (entries[0].from == sample->ip)
a1a58707 1450 goto out;
42bbabed 1451 if (entries[0].flags.abort)
a1a58707 1452 goto out;
48d02a1d
AK
1453
1454 /*
fc5d836c 1455 * Print final block up to sample
61f61159
AK
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
bf0db8c7 1460 * continue walking after the last TO.
48d02a1d 1461 */
42bbabed 1462 start = entries[0].to;
48d02a1d 1463 end = sample->ip;
61f61159
AK
1464 if (end < start) {
1465 /* Missing jump. Scan 128 bytes for the next branch */
1466 end = start + 128;
1467 }
48d02a1d 1468 len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
efff5add 1469 printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, evsel, fp);
48d02a1d
AK
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)
a1a58707 1475 goto out;
6f680c6a 1476 ilen = 0;
218c200f 1477 printed += fprintf(fp, "\t%016" PRIx64 "\t", sample->ip);
efff5add 1478 printed += any_dump_insn(evsel, &x, sample->ip, buffer, len, &ilen, fp);
6f680c6a
KL
1479 if (PRINT_FIELD(BRSTACKINSNLEN))
1480 printed += fprintf(fp, "\tilen: %d", ilen);
1481 printed += fprintf(fp, "\n");
dd2e18e9
AK
1482 if (PRINT_FIELD(SRCCODE))
1483 print_srccode(thread, x.cpumode, sample->ip);
a1a58707 1484 goto out;
48d02a1d
AK
1485 }
1486 for (off = 0; off <= end - start; off += ilen) {
e98df280 1487 ilen = 0;
218c200f 1488 printed += fprintf(fp, "\t%016" PRIx64 "\t", start + off);
efff5add 1489 printed += any_dump_insn(evsel, &x, start + off, buffer + off, len - off, &ilen, fp);
6f680c6a
KL
1490 if (PRINT_FIELD(BRSTACKINSNLEN))
1491 printed += fprintf(fp, "\tilen: %d", ilen);
1492 printed += fprintf(fp, "\n");
48d02a1d
AK
1493 if (ilen == 0)
1494 break;
bf0db8c7
AK
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) {
61f61159
AK
1498 /*
1499 * Hit a missing branch. Just stop.
1500 */
1501 printed += fprintf(fp, "\t... not reaching sample ...\n");
1502 break;
1503 }
dd2e18e9
AK
1504 if (PRINT_FIELD(SRCCODE))
1505 print_srccode(thread, x.cpumode, start + off);
48d02a1d 1506 }
a1a58707
ACM
1507out:
1508 return printed;
48d02a1d 1509}
dc323ce8 1510
a1a58707
ACM
1511static int perf_sample__fprintf_addr(struct perf_sample *sample,
1512 struct thread *thread,
efff5add 1513 struct evsel *evsel, FILE *fp)
7cec0922
DA
1514{
1515 struct addr_location al;
a1a58707 1516 int printed = fprintf(fp, "%16" PRIx64, sample->addr);
7cec0922 1517
0dd5041c 1518 addr_location__init(&al);
efff5add 1519 if (!sample_addr_correlates_sym(&evsel->core.attr))
a1a58707 1520 goto out;
7cec0922 1521
c2740a87 1522 thread__resolve(thread, &al, sample);
7cec0922
DA
1523
1524 if (PRINT_FIELD(SYM)) {
a1a58707 1525 printed += fprintf(fp, " ");
a978f2ab 1526 if (PRINT_FIELD(SYMOFFSET))
a1a58707 1527 printed += symbol__fprintf_symname_offs(al.sym, &al, fp);
a978f2ab 1528 else
a1a58707 1529 printed += symbol__fprintf_symname(al.sym, fp);
7cec0922
DA
1530 }
1531
af9eb56b
CD
1532 if (PRINT_FIELD(DSO))
1533 printed += map__fprintf_dsoname_dsoff(al.map, PRINT_FIELD(DSOFF), al.addr, fp);
a1a58707 1534out:
0dd5041c 1535 addr_location__exit(&al);
a1a58707 1536 return printed;
7cec0922
DA
1537}
1538
99f753f0 1539static const char *resolve_branch_sym(struct perf_sample *sample,
32dcd021 1540 struct evsel *evsel,
99f753f0
AK
1541 struct thread *thread,
1542 struct addr_location *al,
b743b86c 1543 struct addr_location *addr_al,
99f753f0
AK
1544 u64 *ip)
1545{
99f753f0
AK
1546 const char *name = NULL;
1547
1548 if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) {
efff5add 1549 if (sample_addr_correlates_sym(&evsel->core.attr)) {
b743b86c
AH
1550 if (!addr_al->thread)
1551 thread__resolve(thread, addr_al, sample);
1552 if (addr_al->sym)
1553 name = addr_al->sym->name;
99f753f0
AK
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
a1a58707 1568static int perf_sample__fprintf_callindent(struct perf_sample *sample,
32dcd021 1569 struct evsel *evsel,
a1a58707 1570 struct thread *thread,
b743b86c
AH
1571 struct addr_location *al,
1572 struct addr_location *addr_al,
1573 FILE *fp)
e216708d 1574{
256d92bc 1575 size_t depth = thread_stack__depth(thread, sample->cpu);
e216708d
AH
1576 const char *name = NULL;
1577 static int spacing;
1578 int len = 0;
a78cdee6 1579 int dlen = 0;
e216708d
AH
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 */
ee84a303 1586 if (thread__ts(thread) && sample->flags & PERF_IP_FLAG_RETURN)
e216708d
AH
1587 depth += 1;
1588
b743b86c 1589 name = resolve_branch_sym(sample, evsel, thread, al, addr_al, &ip);
e216708d 1590
a78cdee6
AK
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
e216708d 1597 if (name)
a1a58707 1598 len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);
e216708d 1599 else if (ip)
a1a58707 1600 len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip);
e216708d
AH
1601
1602 if (len < 0)
a1a58707 1603 return len;
e216708d
AH
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)
a1a58707
ACM
1613 len += fprintf(fp, "%*s", spacing - len, "");
1614
a78cdee6 1615 return len + dlen;
e216708d
AH
1616}
1617
a1a58707 1618static int perf_sample__fprintf_insn(struct perf_sample *sample,
6f9d8d1d 1619 struct evsel *evsel,
a1a58707
ACM
1620 struct perf_event_attr *attr,
1621 struct thread *thread,
38ab6013
AK
1622 struct machine *machine, FILE *fp,
1623 struct addr_location *al)
224e2c97 1624{
a1a58707
ACM
1625 int printed = 0;
1626
1ff2ca39 1627 script_fetch_insn(sample, thread, machine, native_arch);
3ab481a1 1628
224e2c97 1629 if (PRINT_FIELD(INSNLEN))
a1a58707 1630 printed += fprintf(fp, " ilen: %d", sample->insn_len);
3ab481a1 1631 if (PRINT_FIELD(INSN) && sample->insn_len) {
8f0ec15f
CD
1632 printed += fprintf(fp, " insn: ");
1633 printed += sample__fprintf_insn_raw(sample, fp);
224e2c97 1634 }
99417234
CD
1635 if (PRINT_FIELD(DISASM) && sample->insn_len) {
1636 printed += fprintf(fp, "\t\t");
38ab6013 1637 printed += sample__fprintf_insn_asm(sample, thread, machine, fp, al);
99417234 1638 }
d8120446 1639 if (PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN) || PRINT_FIELD(BRSTACKDISASM))
6f9d8d1d 1640 printed += perf_sample__fprintf_brstackinsn(sample, evsel, thread, attr, machine, fp);
a1a58707
ACM
1641
1642 return printed;
224e2c97
AK
1643}
1644
68fb45bf 1645static int perf_sample__fprintf_ipc(struct perf_sample *sample,
efff5add 1646 struct evsel *evsel, FILE *fp)
68fb45bf
AH
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
a1a58707 1659static int perf_sample__fprintf_bts(struct perf_sample *sample,
32dcd021 1660 struct evsel *evsel,
a1a58707
ACM
1661 struct thread *thread,
1662 struct addr_location *al,
b743b86c 1663 struct addr_location *addr_al,
a1a58707 1664 struct machine *machine, FILE *fp)
95582596 1665{
1fc632ce 1666 struct perf_event_attr *attr = &evsel->core.attr;
efff5add 1667 unsigned int type = evsel__output_type(evsel);
8066be5f 1668 bool print_srcline_last = false;
a1a58707 1669 int printed = 0;
95582596 1670
e216708d 1671 if (PRINT_FIELD(CALLINDENT))
b743b86c 1672 printed += perf_sample__fprintf_callindent(sample, evsel, thread, al, addr_al, fp);
e216708d 1673
95582596
AN
1674 /* print branch_from information */
1675 if (PRINT_FIELD(IP)) {
1405720d 1676 unsigned int print_opts = output[type].print_ip_opts;
e557b674 1677 struct callchain_cursor *cursor = NULL;
8066be5f 1678
8ab12a20
IR
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 }
6f736735 1686 if (cursor == NULL) {
a1a58707 1687 printed += fprintf(fp, " ");
e20ab86e 1688 if (print_opts & EVSEL__PRINT_SRCLINE) {
8066be5f 1689 print_srcline_last = true;
e20ab86e 1690 print_opts &= ~EVSEL__PRINT_SRCLINE;
8066be5f 1691 }
6f736735 1692 } else
a1a58707 1693 printed += fprintf(fp, "\n");
6f736735 1694
9620bc36
ACM
1695 printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor,
1696 symbol_conf.bt_stop_list, fp);
95582596
AN
1697 }
1698
95582596 1699 /* print branch_to information */
243be3dd 1700 if (PRINT_FIELD(ADDR) ||
1fc632ce 1701 ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
1405720d 1702 !output[type].user_set)) {
a1a58707 1703 printed += fprintf(fp, " => ");
efff5add 1704 printed += perf_sample__fprintf_addr(sample, thread, evsel, fp);
578bea40 1705 }
95582596 1706
efff5add 1707 printed += perf_sample__fprintf_ipc(sample, evsel, fp);
68fb45bf 1708
8066be5f 1709 if (print_srcline_last)
a1a58707 1710 printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp);
224e2c97 1711
6f9d8d1d 1712 printed += perf_sample__fprintf_insn(sample, evsel, attr, thread, machine, fp, al);
dd2e18e9
AK
1713 printed += fprintf(fp, "\n");
1714 if (PRINT_FIELD(SRCCODE)) {
1715 int ret = map__fprintf_srccode(al->map, al->addr, stdout,
ee84a303 1716 thread__srccode_state(thread));
dd2e18e9
AK
1717 if (ret) {
1718 printed += ret;
1719 printed += printf("\n");
1720 }
1721 }
1722 return printed;
95582596
AN
1723}
1724
54cd8b03
AH
1725static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
1726{
1727 char str[SAMPLE_FLAGS_BUF_SIZE];
2b747a86 1728 int ret;
055cd33d 1729
2b747a86
LY
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);
400ea6d3
AH
1736}
1737
30372f04
WN
1738struct printer_data {
1739 int line_no;
1740 bool hit_nul;
1741 bool is_printable;
1742};
1743
923d0c9a
ACM
1744static int sample__fprintf_bpf_output(enum binary_printer_ops op,
1745 unsigned int val,
1746 void *extra, FILE *fp)
30372f04
WN
1747{
1748 unsigned char ch = (unsigned char)val;
1749 struct printer_data *printer_data = extra;
923d0c9a 1750 int printed = 0;
30372f04
WN
1751
1752 switch (op) {
1753 case BINARY_PRINT_DATA_BEGIN:
923d0c9a 1754 printed += fprintf(fp, "\n");
30372f04
WN
1755 break;
1756 case BINARY_PRINT_LINE_BEGIN:
923d0c9a 1757 printed += fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" :
30372f04
WN
1758 " ");
1759 break;
1760 case BINARY_PRINT_ADDR:
923d0c9a 1761 printed += fprintf(fp, " %04x:", val);
30372f04
WN
1762 break;
1763 case BINARY_PRINT_NUM_DATA:
923d0c9a 1764 printed += fprintf(fp, " %02x", val);
30372f04
WN
1765 break;
1766 case BINARY_PRINT_NUM_PAD:
923d0c9a 1767 printed += fprintf(fp, " ");
30372f04
WN
1768 break;
1769 case BINARY_PRINT_SEP:
923d0c9a 1770 printed += fprintf(fp, " ");
30372f04
WN
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)) {
923d0c9a 1777 printed += fprintf(fp, "%c", '.');
30372f04
WN
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 {
923d0c9a 1787 printed += fprintf(fp, "%c", ch);
30372f04
WN
1788 }
1789 break;
1790 case BINARY_PRINT_CHAR_PAD:
923d0c9a 1791 printed += fprintf(fp, " ");
30372f04
WN
1792 break;
1793 case BINARY_PRINT_LINE_END:
923d0c9a 1794 printed += fprintf(fp, "\n");
30372f04
WN
1795 printer_data->line_no++;
1796 break;
1797 case BINARY_PRINT_DATA_END:
1798 default:
1799 break;
1800 }
923d0c9a
ACM
1801
1802 return printed;
30372f04
WN
1803}
1804
a1a58707 1805static int perf_sample__fprintf_bpf_output(struct perf_sample *sample, FILE *fp)
30372f04
WN
1806{
1807 unsigned int nr_bytes = sample->raw_size;
1808 struct printer_data printer_data = {0, false, true};
a1a58707
ACM
1809 int printed = binary__fprintf(sample->raw_data, nr_bytes, 8,
1810 sample__fprintf_bpf_output, &printer_data, fp);
30372f04
WN
1811
1812 if (printer_data.is_printable && printer_data.hit_nul)
a1a58707
ACM
1813 printed += fprintf(fp, "%17s \"%s\"\n", "BPF string:", (char *)(sample->raw_data));
1814
1815 return printed;
30372f04
WN
1816}
1817
a1a58707 1818static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp)
65c5e18f
AH
1819{
1820 if (len > 0 && len < spacing)
a1a58707
ACM
1821 return fprintf(fp, "%*s", spacing - len, "");
1822
1823 return 0;
65c5e18f
AH
1824}
1825
a1a58707 1826static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)
65c5e18f 1827{
a1a58707 1828 return perf_sample__fprintf_spacing(len, 34, fp);
65c5e18f
AH
1829}
1830
a5014310
AH
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
a1a58707 1852static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp)
65c5e18f
AH
1853{
1854 struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
a5014310 1855 char str[sizeof(u64) + 1] = "";
65c5e18f 1856 int len;
a5014310 1857 u64 val;
65c5e18f
AH
1858
1859 if (perf_sample__bad_synth_size(sample, *data))
a1a58707 1860 return 0;
65c5e18f 1861
a5014310
AH
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);
a1a58707 1869 return len + perf_sample__fprintf_pt_spacing(len, fp);
65c5e18f
AH
1870}
1871
a1a58707 1872static int perf_sample__fprintf_synth_mwait(struct perf_sample *sample, FILE *fp)
65c5e18f
AH
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))
a1a58707 1878 return 0;
65c5e18f 1879
a1a58707
ACM
1880 len = fprintf(fp, " hints: %#x extensions: %#x ",
1881 data->hints, data->extensions);
1882 return len + perf_sample__fprintf_pt_spacing(len, fp);
65c5e18f
AH
1883}
1884
a1a58707 1885static int perf_sample__fprintf_synth_pwre(struct perf_sample *sample, FILE *fp)
65c5e18f
AH
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))
a1a58707 1891 return 0;
65c5e18f 1892
a1a58707
ACM
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);
65c5e18f
AH
1896}
1897
a1a58707 1898static int perf_sample__fprintf_synth_exstop(struct perf_sample *sample, FILE *fp)
65c5e18f
AH
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))
a1a58707 1904 return 0;
65c5e18f 1905
a1a58707
ACM
1906 len = fprintf(fp, " IP: %u ", data->ip);
1907 return len + perf_sample__fprintf_pt_spacing(len, fp);
65c5e18f
AH
1908}
1909
a1a58707 1910static int perf_sample__fprintf_synth_pwrx(struct perf_sample *sample, FILE *fp)
65c5e18f
AH
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))
a1a58707 1916 return 0;
65c5e18f 1917
a1a58707 1918 len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ",
65c5e18f
AH
1919 data->deepest_cstate, data->last_cstate,
1920 data->wake_reason);
a1a58707 1921 return len + perf_sample__fprintf_pt_spacing(len, fp);
65c5e18f
AH
1922}
1923
a1a58707 1924static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp)
65c5e18f
AH
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))
a1a58707 1931 return 0;
65c5e18f
AH
1932
1933 freq = (le32_to_cpu(data->freq) + 500) / 1000;
a1a58707 1934 len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
65c5e18f
AH
1935 if (data->max_nonturbo) {
1936 percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
a1a58707 1937 len += fprintf(fp, "(%3u%%) ", percent);
65c5e18f 1938 }
a1a58707 1939 return len + perf_sample__fprintf_pt_spacing(len, fp);
65c5e18f
AH
1940}
1941
c840cbfe
AH
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
5b11749b
AH
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",
34f576c9 1960 "SHUTDOWN", NULL, "UINTR", "UIRET"};
5b11749b
AH
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
a48b96ca
AH
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
a1a58707 2004static int perf_sample__fprintf_synth(struct perf_sample *sample,
32dcd021 2005 struct evsel *evsel, FILE *fp)
47e78084 2006{
1fc632ce 2007 switch (evsel->core.attr.config) {
65c5e18f 2008 case PERF_SYNTH_INTEL_PTWRITE:
a1a58707 2009 return perf_sample__fprintf_synth_ptwrite(sample, fp);
65c5e18f 2010 case PERF_SYNTH_INTEL_MWAIT:
a1a58707 2011 return perf_sample__fprintf_synth_mwait(sample, fp);
65c5e18f 2012 case PERF_SYNTH_INTEL_PWRE:
a1a58707 2013 return perf_sample__fprintf_synth_pwre(sample, fp);
65c5e18f 2014 case PERF_SYNTH_INTEL_EXSTOP:
a1a58707 2015 return perf_sample__fprintf_synth_exstop(sample, fp);
65c5e18f 2016 case PERF_SYNTH_INTEL_PWRX:
a1a58707 2017 return perf_sample__fprintf_synth_pwrx(sample, fp);
65c5e18f 2018 case PERF_SYNTH_INTEL_CBR:
a1a58707 2019 return perf_sample__fprintf_synth_cbr(sample, fp);
c840cbfe
AH
2020 case PERF_SYNTH_INTEL_PSB:
2021 return perf_sample__fprintf_synth_psb(sample, fp);
5b11749b
AH
2022 case PERF_SYNTH_INTEL_EVT:
2023 return perf_sample__fprintf_synth_evt(sample, fp);
a48b96ca
AH
2024 case PERF_SYNTH_INTEL_IFLAG_CHG:
2025 return perf_sample__fprintf_synth_iflag_chg(sample, fp);
47e78084
AH
2026 default:
2027 break;
2028 }
a1a58707
ACM
2029
2030 return 0;
47e78084
AH
2031}
2032
afdd63f5 2033static int evlist__max_name_len(struct evlist *evlist)
9cdbc409 2034{
32dcd021 2035 struct evsel *evsel;
9cdbc409
JO
2036 int max = 0;
2037
e5cadb93 2038 evlist__for_each_entry(evlist, evsel) {
8ab2e96d 2039 int len = strlen(evsel__name(evsel));
9cdbc409
JO
2040
2041 max = MAX(len, max);
2042 }
2043
2044 return max;
2045}
2046
a1a58707 2047static int data_src__fprintf(u64 data_src, FILE *fp)
c19ac912 2048{
1a8c2e01 2049 struct mem_info *mi = mem_info__new();
c19ac912
JO
2050 char decode[100];
2051 char out[100];
2052 static int maxlen;
2053 int len;
2054
1a8c2e01
IR
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);
c19ac912
JO
2061
2062 len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode);
2063 if (maxlen < len)
2064 maxlen = len;
2065
a1a58707 2066 return fprintf(fp, "%-*s", maxlen, out);
c19ac912
JO
2067}
2068
4bd1bef8
AK
2069struct metric_ctx {
2070 struct perf_sample *sample;
2071 struct thread *thread;
32dcd021 2072 struct evsel *evsel;
4bd1bef8
AK
2073 FILE *fp;
2074};
2075
6ca9a082 2076static void script_print_metric(struct perf_stat_config *config __maybe_unused,
37b77ae9
IR
2077 void *ctx, enum metric_threshold_classify thresh,
2078 const char *fmt, const char *unit, double val)
4bd1bef8
AK
2079{
2080 struct metric_ctx *mctx = ctx;
37b77ae9 2081 const char *color = metric_threshold_classify__color(thresh);
4bd1bef8
AK
2082
2083 if (!fmt)
2084 return;
e534bfb1 2085 perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
28a0b398 2086 PERF_RECORD_SAMPLE, mctx->fp);
4bd1bef8
AK
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
6ca9a082
JO
2095static void script_new_line(struct perf_stat_config *config __maybe_unused,
2096 void *ctx)
4bd1bef8
AK
2097{
2098 struct metric_ctx *mctx = ctx;
2099
e534bfb1 2100 perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel,
28a0b398 2101 PERF_RECORD_SAMPLE, mctx->fp);
4bd1bef8
AK
2102 fputs("\tmetric: ", mctx->fp);
2103}
2104
2105static void perf_sample__fprint_metric(struct perf_script *script,
2106 struct thread *thread,
32dcd021 2107 struct evsel *evsel,
4bd1bef8
AK
2108 struct perf_sample *sample,
2109 FILE *fp)
2110{
fba7c866 2111 struct evsel *leader = evsel__leader(evsel);
4bd1bef8
AK
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 };
32dcd021 2123 struct evsel *ev2;
4bd1bef8
AK
2124 u64 val;
2125
4bd1bef8 2126 if (!evsel->stats)
1f297a6e 2127 evlist__alloc_stats(&stat_config, script->session->evlist, /*alloc_raw=*/false);
fba7c866 2128 if (evsel_script(leader)->gnum++ == 0)
4bd1bef8
AK
2129 perf_stat__reset_shadow_stats();
2130 val = sample->period * evsel->scale;
4bd1bef8 2131 evsel_script(evsel)->val = val;
fba7c866
JO
2132 if (evsel_script(leader)->gnum == leader->core.nr_members) {
2133 for_each_group_member (ev2, leader) {
6ca9a082 2134 perf_stat__print_shadow_stats(&stat_config, ev2,
4bd1bef8
AK
2135 evsel_script(ev2)->val,
2136 sample->cpu,
2137 &ctx,
cc26ffaa 2138 NULL);
4bd1bef8 2139 }
fba7c866 2140 evsel_script(leader)->gnum = 0;
4bd1bef8
AK
2141 }
2142}
2143
99f753f0 2144static bool show_event(struct perf_sample *sample,
32dcd021 2145 struct evsel *evsel,
99f753f0 2146 struct thread *thread,
b743b86c
AH
2147 struct addr_location *al,
2148 struct addr_location *addr_al)
99f753f0 2149{
256d92bc 2150 int depth = thread_stack__depth(thread, sample->cpu);
99f753f0
AK
2151
2152 if (!symbol_conf.graph_function)
2153 return true;
2154
ee84a303
IR
2155 if (thread__filter(thread)) {
2156 if (depth <= thread__filter_entry_depth(thread)) {
2157 thread__set_filter(thread, false);
99f753f0
AK
2158 return false;
2159 }
2160 return true;
2161 } else {
2162 const char *s = symbol_conf.graph_function;
2163 u64 ip;
b743b86c 2164 const char *name = resolve_branch_sym(sample, evsel, thread, al, addr_al,
99f753f0
AK
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)) {
ee84a303
IR
2174 thread__set_filter(thread, true);
2175 thread__set_filter_entry_depth(thread, depth);
99f753f0
AK
2176 return true;
2177 }
2178 s += len;
2179 if (*s == ',')
2180 s++;
2181 }
2182 return false;
2183 }
2184}
2185
a3dff304 2186static void process_event(struct perf_script *script,
32dcd021 2187 struct perf_sample *sample, struct evsel *evsel,
48d02a1d 2188 struct addr_location *al,
b743b86c 2189 struct addr_location *addr_al,
48d02a1d 2190 struct machine *machine)
be6d842a 2191{
f9d5d549 2192 struct thread *thread = al->thread;
1fc632ce 2193 struct perf_event_attr *attr = &evsel->core.attr;
efff5add 2194 unsigned int type = evsel__output_type(evsel);
32dcd021 2195 struct evsel_script *es = evsel->priv;
642ee1c6 2196 FILE *fp = es->fp;
6b9bae63 2197 char str[PAGE_SIZE_NAME_LEN];
83869019 2198 const char *arch = perf_env__arch(machine->env);
1424dc96 2199
1405720d 2200 if (output[type].fields == 0)
1424dc96
DA
2201 return;
2202
642ee1c6
ACM
2203 ++es->samples;
2204
e534bfb1 2205 perf_sample__fprintf_start(script, sample, thread, evsel,
28a0b398 2206 PERF_RECORD_SAMPLE, fp);
745f43e3 2207
535aeaae 2208 if (PRINT_FIELD(PERIOD))
69c71252 2209 fprintf(fp, "%10" PRIu64 " ", sample->period);
535aeaae 2210
e944d3d7 2211 if (PRINT_FIELD(EVNAME)) {
8ab2e96d 2212 const char *evname = evsel__name(evsel);
9cdbc409
JO
2213
2214 if (!script->name_width)
afdd63f5 2215 script->name_width = evlist__max_name_len(script->session->evlist);
9cdbc409 2216
69c71252 2217 fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]");
e944d3d7
NK
2218 }
2219
400ea6d3 2220 if (print_flags)
a1a58707 2221 perf_sample__fprintf_flags(sample->flags, fp);
400ea6d3 2222
95582596 2223 if (is_bts_event(attr)) {
b743b86c 2224 perf_sample__fprintf_bts(sample, evsel, thread, al, addr_al, machine, fp);
95582596
AN
2225 return;
2226 }
378ef0f5 2227#ifdef HAVE_LIBTRACEEVENT
96167167 2228 if (PRINT_FIELD(TRACE) && sample->raw_data) {
c46d634a
IR
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 }
894f3f17 2236 }
378ef0f5 2237#endif
47e78084 2238 if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
a1a58707 2239 perf_sample__fprintf_synth(sample, evsel, fp);
47e78084 2240
7cec0922 2241 if (PRINT_FIELD(ADDR))
efff5add 2242 perf_sample__fprintf_addr(sample, thread, evsel, fp);
7cec0922 2243
94ddddfa 2244 if (PRINT_FIELD(DATA_SRC))
a1a58707 2245 data_src__fprintf(sample->data_src, fp);
94ddddfa
JO
2246
2247 if (PRINT_FIELD(WEIGHT))
a1a58707 2248 fprintf(fp, "%16" PRIu64, sample->weight);
94ddddfa 2249
6ea5d1a3
KL
2250 if (PRINT_FIELD(INS_LAT))
2251 fprintf(fp, "%16" PRIu16, sample->ins_lat);
2252
17f248aa
KL
2253 if (PRINT_FIELD(RETIRE_LAT))
2254 fprintf(fp, "%16" PRIu16, sample->retire_lat);
2255
8c49c6e1
IB
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
787bef17 2267 if (PRINT_FIELD(IP)) {
e557b674 2268 struct callchain_cursor *cursor = NULL;
6f736735 2269
680d125c 2270 if (script->stitch_lbr)
ee84a303 2271 thread__set_lbr_stitch_enable(al->thread, true);
680d125c 2272
8ab12a20
IR
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 }
a1a58707 2280 fputc(cursor ? '\n' : ' ', fp);
9620bc36
ACM
2281 sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor,
2282 symbol_conf.bt_stop_list, fp);
c0230b2b
DA
2283 }
2284
fc36f948 2285 if (PRINT_FIELD(IREGS))
83869019 2286 perf_sample__fprintf_iregs(sample, attr, arch, fp);
fc36f948 2287
b1491ace 2288 if (PRINT_FIELD(UREGS))
83869019 2289 perf_sample__fprintf_uregs(sample, attr, arch, fp);
b1491ace 2290
dc323ce8 2291 if (PRINT_FIELD(BRSTACK))
efff5add 2292 perf_sample__fprintf_brstack(sample, thread, evsel, fp);
dc323ce8 2293 else if (PRINT_FIELD(BRSTACKSYM))
efff5add 2294 perf_sample__fprintf_brstacksym(sample, thread, evsel, fp);
106dacd8 2295 else if (PRINT_FIELD(BRSTACKOFF))
efff5add 2296 perf_sample__fprintf_brstackoff(sample, thread, evsel, fp);
dc323ce8 2297
8ae7a576 2298 if (evsel__is_bpf_output(evsel) && !evsel__is_offcpu_event(evsel) && PRINT_FIELD(BPF_OUTPUT))
a1a58707 2299 perf_sample__fprintf_bpf_output(sample, fp);
6f9d8d1d 2300 perf_sample__fprintf_insn(sample, evsel, attr, thread, machine, fp, al);
49d58f04
KL
2301
2302 if (PRINT_FIELD(PHYS_ADDR))
69c71252 2303 fprintf(fp, "%16" PRIx64, sample->phys_addr);
68fb45bf 2304
6b9bae63
KL
2305 if (PRINT_FIELD(DATA_PAGE_SIZE))
2306 fprintf(fp, " %s", get_page_size_name(sample->data_page_size, str));
2307
c513de8a
SE
2308 if (PRINT_FIELD(CODE_PAGE_SIZE))
2309 fprintf(fp, " %s", get_page_size_name(sample->code_page_size, str));
2310
efff5add 2311 perf_sample__fprintf_ipc(sample, evsel, fp);
68fb45bf 2312
69c71252 2313 fprintf(fp, "\n");
4bd1bef8 2314
dd2e18e9
AK
2315 if (PRINT_FIELD(SRCCODE)) {
2316 if (map__fprintf_srccode(al->map, al->addr, stdout,
ee84a303 2317 thread__srccode_state(thread)))
dd2e18e9
AK
2318 printf("\n");
2319 }
2320
4bd1bef8
AK
2321 if (PRINT_FIELD(METRIC))
2322 perf_sample__fprint_metric(script, thread, evsel, sample, fp);
7ee40678 2323
7c0a6144 2324 if (verbose > 0)
7ee40678 2325 fflush(fp);
be6d842a
DA
2326}
2327
956ffd02
TZ
2328static struct scripting_ops *scripting_ops;
2329
32dcd021 2330static void __process_stat(struct evsel *counter, u64 tstamp)
36e33c53 2331{
a2f354e3 2332 int nthreads = perf_thread_map__nr(counter->core.threads);
6d18804b
IR
2333 int idx, thread;
2334 struct perf_cpu cpu;
36e33c53
JO
2335 static int header_printed;
2336
36e33c53
JO
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++) {
f9551b3f 2344 perf_cpu_map__for_each_cpu(cpu, idx, evsel__cpus(counter)) {
36e33c53
JO
2345 struct perf_counts_values *counts;
2346
b57af1b4 2347 counts = perf_counts(counter->counts, idx, thread);
36e33c53
JO
2348
2349 printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n",
6d18804b 2350 cpu.cpu,
a2f354e3 2351 perf_thread_map__pid(counter->core.threads, thread),
36e33c53
JO
2352 counts->val,
2353 counts->ena,
2354 counts->run,
2355 tstamp,
8ab2e96d 2356 evsel__name(counter));
36e33c53
JO
2357 }
2358 }
2359}
2360
32dcd021 2361static void process_stat(struct evsel *counter, u64 tstamp)
e099eba8
JO
2362{
2363 if (scripting_ops && scripting_ops->process_stat)
2364 scripting_ops->process_stat(&stat_config, counter, tstamp);
36e33c53
JO
2365 else
2366 __process_stat(counter, tstamp);
e099eba8
JO
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
956ffd02
TZ
2375static void setup_scripting(void)
2376{
378ef0f5 2377#ifdef HAVE_LIBTRACEEVENT
16c632de 2378 setup_perl_scripting();
378ef0f5 2379#endif
80c3a7d9 2380 setup_python_scripting();
956ffd02
TZ
2381}
2382
d445dd2a
AH
2383static int flush_scripting(void)
2384{
2aaecfc5 2385 return scripting_ops ? scripting_ops->flush_script() : 0;
d445dd2a
AH
2386}
2387
956ffd02
TZ
2388static int cleanup_scripting(void)
2389{
133dc4c3 2390 pr_debug("\nperf script stopped\n");
3824a4e8 2391
2aaecfc5 2392 return scripting_ops ? scripting_ops->stop_script() : 0;
956ffd02
TZ
2393}
2394
e87e5481
AK
2395static bool filter_cpu(struct perf_sample *sample)
2396{
1a2725f3 2397 if (cpu_list && sample->cpu != (u32)-1)
e87e5481
AK
2398 return !test_bit(sample->cpu, cpu_bitmap);
2399 return false;
2400}
2401
30f29bae 2402static int process_sample_event(const struct perf_tool *tool,
d20deb64 2403 union perf_event *event,
8115d60c 2404 struct perf_sample *sample,
32dcd021 2405 struct evsel *evsel,
743eb868 2406 struct machine *machine)
5f9c39dc 2407{
809e9423 2408 struct perf_script *scr = container_of(tool, struct perf_script, tool);
e7984b7b 2409 struct addr_location al;
b743b86c 2410 struct addr_location addr_al;
291961fc 2411 int ret = 0;
5f9c39dc 2412
9bde93a7 2413 /* Set thread to NULL to indicate addr_al and al are not initialized */
0dd5041c
IR
2414 addr_location__init(&al);
2415 addr_location__init(&addr_al);
9bde93a7
AH
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
2ab046cd
JY
2424 if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num,
2425 sample->time)) {
9bde93a7 2426 goto out_put;
2ab046cd 2427 }
a91f4c47 2428
1424dc96
DA
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++;
e1889d75 2435 }
1424dc96 2436 last_timestamp = sample->time;
9bde93a7 2437 goto out_put;
5f9c39dc 2438 }
5d67be97 2439
9300041c 2440 if (filter_cpu(sample))
9bde93a7 2441 goto out_put;
9300041c 2442
29159727 2443 if (!al.thread && machine__resolve(machine, &al, sample) < 0) {
e7984b7b
DA
2444 pr_err("problem processing %d event, skipping it.\n",
2445 event->header.type);
9bde93a7
AH
2446 ret = -1;
2447 goto out_put;
e7984b7b
DA
2448 }
2449
2450 if (al.filtered)
b91fc39f 2451 goto out_put;
e7984b7b 2452
b743b86c 2453 if (!show_event(sample, evsel, al.thread, &al, &addr_al))
4371fbc0
AH
2454 goto out_put;
2455
2456 if (evswitch__discard(&scr->evswitch, evsel))
2457 goto out_put;
2458
291961fc
AH
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
3f8e009e
AH
2466 if (scripting_ops) {
2467 struct addr_location *addr_al_ptr = NULL;
3f8e009e
AH
2468
2469 if ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
2470 sample_addr_correlates_sym(&evsel->core.attr)) {
b743b86c
AH
2471 if (!addr_al.thread)
2472 thread__resolve(al.thread, &addr_al, sample);
3f8e009e
AH
2473 addr_al_ptr = &addr_al;
2474 }
2475 scripting_ops->process_event(event, sample, evsel, &al, addr_al_ptr);
2476 } else {
b743b86c 2477 process_event(scr, sample, evsel, &al, &addr_al, machine);
3f8e009e 2478 }
2aaecfc5 2479
b91fc39f 2480out_put:
0dd5041c
IR
2481 addr_location__exit(&addr_al);
2482 addr_location__exit(&al);
291961fc 2483 return ret;
5f9c39dc
FW
2484}
2485
36d3e413
ACM
2486// Used when scr->per_event_dump is not set
2487static struct evsel_script es_stdout;
2488
30f29bae 2489static int process_attr(const struct perf_tool *tool, union perf_event *event,
63503dba 2490 struct evlist **pevlist)
7ea95727
AH
2491{
2492 struct perf_script *scr = container_of(tool, struct perf_script, tool);
63503dba 2493 struct evlist *evlist;
32dcd021 2494 struct evsel *evsel, *pos;
0d71a2b2 2495 u64 sample_type;
7ea95727
AH
2496 int err;
2497
2498 err = perf_event__process_attr(tool, event, pevlist);
2499 if (err)
2500 return err;
2501
2502 evlist = *pevlist;
515dbe48 2503 evsel = evlist__last(*pevlist);
7ea95727 2504
a3af66f5 2505 if (!evsel->priv) {
1a8c2e01 2506 if (scr->per_event_dump) {
297e69bf 2507 evsel->priv = evsel_script__new(evsel, scr->session->data);
36d3e413 2508 if (!evsel->priv)
a3af66f5 2509 return -ENOMEM;
36d3e413
ACM
2510 } else { // Replicate what is done in perf_script__setup_per_event_dump()
2511 es_stdout.fp = stdout;
2512 evsel->priv = &es_stdout;
a3af66f5
RB
2513 }
2514 }
2515
1fc632ce
JO
2516 if (evsel->core.attr.type >= PERF_TYPE_MAX &&
2517 evsel->core.attr.type != PERF_TYPE_SYNTH)
7ea95727
AH
2518 return 0;
2519
e5cadb93 2520 evlist__for_each_entry(evlist, pos) {
1fc632ce 2521 if (pos->core.attr.type == evsel->core.attr.type && pos != evsel)
7ea95727
AH
2522 return 0;
2523 }
2524
0d71a2b2 2525 if (evsel->core.attr.sample_type) {
afdd63f5 2526 err = evsel__check_attr(evsel, scr->session);
0d71a2b2
JO
2527 if (err)
2528 return err;
2529 }
d2b5a315 2530
0d71a2b2
JO
2531 /*
2532 * Check if we need to enable callchains based
2533 * on events sample_type.
2534 */
b3c2cc2b 2535 sample_type = evlist__combined_sample_type(evlist);
aa8db3e4 2536 callchain_param_setup(sample_type, perf_env__arch((*pevlist)->env));
53fb1894 2537
b5164085
AH
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))) {
efff5add 2544 int type = evsel__output_type(evsel);
b5164085
AH
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;
53fb1894 2550 }
efff5add 2551 evsel__set_print_ip_opts(evsel);
0d71a2b2 2552 return 0;
7ea95727
AH
2553}
2554
30f29bae 2555static int print_event_with_time(const struct perf_tool *tool,
1a2725f3
AH
2556 union perf_event *event,
2557 struct perf_sample *sample,
2558 struct machine *machine,
2559 pid_t pid, pid_t tid, u64 timestamp)
ad7ebb9a 2560{
ad7ebb9a
NK
2561 struct perf_script *script = container_of(tool, struct perf_script, tool);
2562 struct perf_session *session = script->session;
3ccf8a7b 2563 struct evsel *evsel = evlist__id2evsel(session->evlist, sample->id);
1a2725f3 2564 struct thread *thread = NULL;
ad7ebb9a 2565
1a2725f3
AH
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;
ad7ebb9a
NK
2571 }
2572
1a2725f3
AH
2573 if (filter_cpu(sample))
2574 return 0;
ad7ebb9a 2575
1a2725f3
AH
2576 if (tid != -1)
2577 thread = machine__findnew_thread(machine, pid, tid);
2578
fc18380f 2579 if (evsel) {
e534bfb1 2580 perf_sample__fprintf_start(script, sample, thread, evsel,
1a2725f3 2581 event->header.type, stdout);
e87e5481 2582 }
1a2725f3 2583
7eeb9855 2584 perf_event__fprintf(event, machine, stdout);
1a2725f3 2585
b91fc39f 2586 thread__put(thread);
1a2725f3
AH
2587
2588 return 0;
2589}
2590
30f29bae 2591static int print_event(const struct perf_tool *tool, union perf_event *event,
1a2725f3
AH
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
30f29bae 2598static int process_comm_event(const struct perf_tool *tool,
1a2725f3
AH
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);
ad7ebb9a
NK
2608}
2609
30f29bae 2610static int process_namespaces_event(const struct perf_tool *tool,
96a44bbc
HB
2611 union perf_event *event,
2612 struct perf_sample *sample,
2613 struct machine *machine)
2614{
96a44bbc 2615 if (perf_event__process_namespaces(tool, event, sample, machine) < 0)
1a2725f3 2616 return -1;
96a44bbc 2617
1a2725f3
AH
2618 return print_event(tool, event, sample, machine, event->namespaces.pid,
2619 event->namespaces.tid);
96a44bbc
HB
2620}
2621
30f29bae 2622static int process_cgroup_event(const struct perf_tool *tool,
160d4af9
NK
2623 union perf_event *event,
2624 struct perf_sample *sample,
2625 struct machine *machine)
2626{
160d4af9 2627 if (perf_event__process_cgroup(tool, event, sample, machine) < 0)
1a2725f3 2628 return -1;
160d4af9 2629
1a2725f3
AH
2630 return print_event(tool, event, sample, machine, sample->pid,
2631 sample->tid);
160d4af9
NK
2632}
2633
30f29bae 2634static int process_fork_event(const struct perf_tool *tool,
ad7ebb9a
NK
2635 union perf_event *event,
2636 struct perf_sample *sample,
2637 struct machine *machine)
2638{
ad7ebb9a
NK
2639 if (perf_event__process_fork(tool, event, sample, machine) < 0)
2640 return -1;
2641
1a2725f3
AH
2642 return print_event_with_time(tool, event, sample, machine,
2643 event->fork.pid, event->fork.tid,
2644 event->fork.time);
ad7ebb9a 2645}
30f29bae 2646static int process_exit_event(const struct perf_tool *tool,
ad7ebb9a
NK
2647 union perf_event *event,
2648 struct perf_sample *sample,
2649 struct machine *machine)
2650{
1a2725f3
AH
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))
ad7ebb9a 2654 return -1;
ad7ebb9a 2655
1a2725f3 2656 return perf_event__process_exit(tool, event, sample, machine);
ad7ebb9a
NK
2657}
2658
30f29bae 2659static int process_mmap_event(const struct perf_tool *tool,
ba1ddf42
NK
2660 union perf_event *event,
2661 struct perf_sample *sample,
2662 struct machine *machine)
2663{
ba1ddf42
NK
2664 if (perf_event__process_mmap(tool, event, sample, machine) < 0)
2665 return -1;
2666
1a2725f3
AH
2667 return print_event(tool, event, sample, machine, event->mmap.pid,
2668 event->mmap.tid);
ba1ddf42
NK
2669}
2670
30f29bae 2671static int process_mmap2_event(const struct perf_tool *tool,
ba1ddf42
NK
2672 union perf_event *event,
2673 struct perf_sample *sample,
2674 struct machine *machine)
2675{
ba1ddf42
NK
2676 if (perf_event__process_mmap2(tool, event, sample, machine) < 0)
2677 return -1;
2678
1a2725f3
AH
2679 return print_event(tool, event, sample, machine, event->mmap2.pid,
2680 event->mmap2.tid);
ba1ddf42
NK
2681}
2682
30f29bae 2683static int process_switch_event(const struct perf_tool *tool,
7c14898b
AH
2684 union perf_event *event,
2685 struct perf_sample *sample,
2686 struct machine *machine)
2687{
7c14898b 2688 struct perf_script *script = container_of(tool, struct perf_script, tool);
7c14898b
AH
2689
2690 if (perf_event__process_switch(tool, event, sample, machine) < 0)
2691 return -1;
2692
5e0c325c 2693 if (scripting_ops && scripting_ops->process_switch && !filter_cpu(sample))
5bf83c29
AH
2694 scripting_ops->process_switch(event, sample, machine);
2695
2696 if (!script->show_switch_events)
2697 return 0;
2698
1a2725f3
AH
2699 return print_event(tool, event, sample, machine, sample->pid,
2700 sample->tid);
7c14898b
AH
2701}
2702
2ede9217
AH
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
3d7c27b6 2714static int
30f29bae 2715process_lost_event(const struct perf_tool *tool,
3d7c27b6
JO
2716 union perf_event *event,
2717 struct perf_sample *sample,
2718 struct machine *machine)
2719{
1a2725f3
AH
2720 return print_event(tool, event, sample, machine, sample->pid,
2721 sample->tid);
3d7c27b6
JO
2722}
2723
538d9c18 2724static int
30f29bae 2725process_throttle_event(const struct perf_tool *tool __maybe_unused,
538d9c18
SB
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
3233b37a 2735static int
30f29bae 2736process_finished_round_event(const struct perf_tool *tool __maybe_unused,
3233b37a
JO
2737 union perf_event *event,
2738 struct ordered_events *oe __maybe_unused)
2739
2740{
7eeb9855 2741 perf_event__fprintf(event, NULL, stdout);
3233b37a
JO
2742 return 0;
2743}
2744
490c8cc9 2745static int
30f29bae 2746process_bpf_events(const struct perf_tool *tool __maybe_unused,
490c8cc9
JO
2747 union perf_event *event,
2748 struct perf_sample *sample,
2749 struct machine *machine)
2750{
490c8cc9
JO
2751 if (machine__process_ksymbol(machine, event, sample) < 0)
2752 return -1;
2753
1a2725f3
AH
2754 return print_event(tool, event, sample, machine, sample->pid,
2755 sample->tid);
490c8cc9
JO
2756}
2757
30f29bae 2758static int process_text_poke_events(const struct perf_tool *tool,
92ecf3a6
AH
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
1d037ca1 2770static void sig_handler(int sig __maybe_unused)
c239da3b
TZ
2771{
2772 session_done = 1;
2773}
2774
a14390fd
ACM
2775static void perf_script__fclose_per_event_dump(struct perf_script *script)
2776{
63503dba 2777 struct evlist *evlist = script->session->evlist;
32dcd021 2778 struct evsel *evsel;
a14390fd
ACM
2779
2780 evlist__for_each_entry(evlist, evsel) {
2781 if (!evsel->priv)
2782 break;
297e69bf 2783 evsel_script__delete(evsel->priv);
a14390fd
ACM
2784 evsel->priv = NULL;
2785 }
2786}
2787
2788static int perf_script__fopen_per_event_dump(struct perf_script *script)
2789{
32dcd021 2790 struct evsel *evsel;
a14390fd
ACM
2791
2792 evlist__for_each_entry(script->session->evlist, evsel) {
fa48c892
ACM
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
4d39c89f 2796 * for the evsels synthesized from the auxtrace info.
fa48c892
ACM
2797 *
2798 * Ses perf_script__process_auxtrace_info.
2799 */
2800 if (evsel->priv != NULL)
2801 continue;
2802
297e69bf 2803 evsel->priv = evsel_script__new(evsel, script->session->data);
a14390fd
ACM
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{
32dcd021 2817 struct evsel *evsel;
a14390fd
ACM
2818
2819 if (script->per_event_dump)
2820 return perf_script__fopen_per_event_dump(script);
2821
642ee1c6
ACM
2822 es_stdout.fp = stdout;
2823
a14390fd 2824 evlist__for_each_entry(script->session->evlist, evsel)
642ee1c6 2825 evsel->priv = &es_stdout;
a14390fd
ACM
2826
2827 return 0;
2828}
2829
642ee1c6
ACM
2830static void perf_script__exit_per_event_dump_stats(struct perf_script *script)
2831{
32dcd021 2832 struct evsel *evsel;
642ee1c6
ACM
2833
2834 evlist__for_each_entry(script->session->evlist, evsel) {
32dcd021 2835 struct evsel_script *es = evsel->priv;
642ee1c6 2836
297e69bf
ACM
2837 evsel_script__fprintf(es, stdout);
2838 evsel_script__delete(es);
642ee1c6
ACM
2839 evsel->priv = NULL;
2840 }
2841}
2842
faf3ac30
RM
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
6f3e5eda 2849static int __cmd_script(struct perf_script *script)
5f9c39dc 2850{
6fcf7ddb
FW
2851 int ret;
2852
c239da3b
TZ
2853 signal(SIGINT, sig_handler);
2854
ad7ebb9a
NK
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 }
ba1ddf42
NK
2861 if (script->show_mmap_events) {
2862 script->tool.mmap = process_mmap_event;
2863 script->tool.mmap2 = process_mmap2_event;
2864 }
5bf83c29 2865 if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch))
7c14898b 2866 script->tool.context_switch = process_switch_event;
2ede9217
AH
2867 if (scripting_ops && scripting_ops->process_auxtrace_error)
2868 script->tool.auxtrace_error = process_auxtrace_error;
96a44bbc
HB
2869 if (script->show_namespace_events)
2870 script->tool.namespaces = process_namespaces_event;
160d4af9
NK
2871 if (script->show_cgroup_events)
2872 script->tool.cgroup = process_cgroup_event;
3d7c27b6
JO
2873 if (script->show_lost_events)
2874 script->tool.lost = process_lost_event;
3233b37a
JO
2875 if (script->show_round_events) {
2876 script->tool.ordered_events = false;
2877 script->tool.finished_round = process_finished_round_event;
2878 }
490c8cc9 2879 if (script->show_bpf_events) {
3f604b5f
ACM
2880 script->tool.ksymbol = process_bpf_events;
2881 script->tool.bpf = process_bpf_events;
490c8cc9 2882 }
92ecf3a6
AH
2883 if (script->show_text_poke_events) {
2884 script->tool.ksymbol = process_bpf_events;
2885 script->tool.text_poke = process_text_poke_events;
2886 }
ad7ebb9a 2887
a14390fd
ACM
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
b7b61cbe 2893 ret = perf_session__process_events(script->session);
6fcf7ddb 2894
a14390fd 2895 if (script->per_event_dump)
642ee1c6 2896 perf_script__exit_per_event_dump_stats(script);
a14390fd 2897
6d8afb56 2898 if (debug_mode)
9486aa38 2899 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
6fcf7ddb
FW
2900
2901 return ret;
5f9c39dc
FW
2902}
2903
04051b4a 2904static int list_available_languages_cb(struct scripting_ops *ops, const char *spec)
956ffd02 2905{
04051b4a 2906 fprintf(stderr, " %-42s [%s]\n", spec, ops->name);
956ffd02
TZ
2907 return 0;
2908}
2909
956ffd02
TZ
2910static void list_available_languages(void)
2911{
956ffd02
TZ
2912 fprintf(stderr, "\n");
2913 fprintf(stderr, "Scripting language extensions (used in "
133dc4c3 2914 "perf script -s [spec:]script.[spec]):\n\n");
04051b4a 2915 script_spec__for_each(&list_available_languages_cb);
956ffd02
TZ
2916 fprintf(stderr, "\n");
2917}
2918
6ea4b5db
AH
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
1d037ca1
IT
2950static int parse_scriptname(const struct option *opt __maybe_unused,
2951 const char *str, int unset __maybe_unused)
956ffd02
TZ
2952{
2953 char spec[PATH_MAX];
2954 const char *script, *ext;
2955 int len;
2956
f526d68b 2957 if (strcmp(str, "lang") == 0) {
956ffd02 2958 list_available_languages();
f526d68b 2959 exit(0);
956ffd02
TZ
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;
d1e95bb5 2979 ext = strrchr(script, '.');
956ffd02
TZ
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
6ea4b5db
AH
2991 script_name = find_script(script);
2992 if (!script_name)
2993 script_name = strdup(script);
956ffd02
TZ
2994
2995 return 0;
2996}
2997
1d037ca1
IT
2998static int parse_output_fields(const struct option *opt __maybe_unused,
2999 const char *arg, int unset __maybe_unused)
745f43e3 3000{
49346e85 3001 char *tok, *strtok_saveptr = NULL;
50ca19ae 3002 int i, imax = ARRAY_SIZE(all_output_options);
2c9e45f7 3003 int j;
745f43e3
DA
3004 int rc = 0;
3005 char *str = strdup(arg);
1424dc96 3006 int type = -1;
36ce5651 3007 enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;
745f43e3
DA
3008
3009 if (!str)
3010 return -ENOMEM;
3011
2c9e45f7
DA
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.
1424dc96 3015 */
2c9e45f7
DA
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;
0817a6a3
AS
3026 else if (!strcmp(str, "raw"))
3027 type = PERF_TYPE_RAW;
27cfef00
WN
3028 else if (!strcmp(str, "break"))
3029 type = PERF_TYPE_BREAKPOINT;
1405720d
AH
3030 else if (!strcmp(str, "synth"))
3031 type = OUTPUT_TYPE_SYNTH;
2c9e45f7
DA
3032 else {
3033 fprintf(stderr, "Invalid event type in field string.\n");
38efb539
RR
3034 rc = -EINVAL;
3035 goto out;
2c9e45f7
DA
3036 }
3037
3038 if (output[type].user_set)
3039 pr_warning("Overriding previous field request for %s events.\n",
3040 event_type(type));
3041
6ef362fd
JO
3042 /* Don't override defaults for +- */
3043 if (strchr(tok, '+') || strchr(tok, '-'))
3044 goto parse;
3045
2c9e45f7
DA
3046 output[type].fields = 0;
3047 output[type].user_set = true;
9cbdb702 3048 output[type].wildcard_set = false;
2c9e45f7
DA
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
36ce5651
AK
3059 /* Don't override defaults for +- */
3060 if (strchr(str, '+') || strchr(str, '-'))
3061 goto parse;
3062
2c9e45f7
DA
3063 if (output_set_by_user())
3064 pr_warning("Overriding previous field request for all events.\n");
3065
1405720d 3066 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2c9e45f7
DA
3067 output[j].fields = 0;
3068 output[j].user_set = true;
9cbdb702 3069 output[j].wildcard_set = true;
2c9e45f7 3070 }
745f43e3
DA
3071 }
3072
36ce5651 3073parse:
49346e85 3074 for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
36ce5651
AK
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
745f43e3 3091 for (i = 0; i < imax; ++i) {
2c9e45f7 3092 if (strcmp(tok, all_output_options[i].str) == 0)
745f43e3 3093 break;
745f43e3 3094 }
400ea6d3 3095 if (i == imax && strcmp(tok, "flags") == 0) {
8524711d 3096 print_flags = change != REMOVE;
400ea6d3
AH
3097 continue;
3098 }
745f43e3 3099 if (i == imax) {
2c9e45f7 3100 fprintf(stderr, "Invalid field requested.\n");
745f43e3 3101 rc = -EINVAL;
2c9e45f7 3102 goto out;
745f43e3 3103 }
99417234
CD
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
745f43e3 3111
2c9e45f7
DA
3112 if (type == -1) {
3113 /* add user option to all events types for
3114 * which it is valid
3115 */
1405720d 3116 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2c9e45f7
DA
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));
36ce5651 3120 } else {
4b6ac811 3121 if (change == REMOVE) {
36ce5651 3122 output[j].fields &= ~all_output_options[i].field;
4b6ac811 3123 output[j].user_set_fields &= ~all_output_options[i].field;
b5164085 3124 output[j].user_unset_fields |= all_output_options[i].field;
4b6ac811 3125 } else {
36ce5651 3126 output[j].fields |= all_output_options[i].field;
4b6ac811 3127 output[j].user_set_fields |= all_output_options[i].field;
b5164085 3128 output[j].user_unset_fields &= ~all_output_options[i].field;
4b6ac811 3129 }
37fed3de
AK
3130 output[j].user_set = true;
3131 output[j].wildcard_set = true;
36ce5651 3132 }
2c9e45f7
DA
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 }
6ef362fd
JO
3142 if (change == REMOVE)
3143 output[type].fields &= ~all_output_options[i].field;
3144 else
3145 output[type].fields |= all_output_options[i].field;
37fed3de
AK
3146 output[type].user_set = true;
3147 output[type].wildcard_set = true;
2c9e45f7 3148 }
745f43e3
DA
3149 }
3150
2c9e45f7
DA
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 }
36ce5651 3157 goto out;
745f43e3 3158
36ce5651
AK
3159out_badmix:
3160 fprintf(stderr, "Cannot mix +-field with overridden fields\n");
3161 rc = -EINVAL;
2c9e45f7 3162out:
745f43e3
DA
3163 free(str);
3164 return rc;
3165}
3166
a5e8e825
ACM
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)))
4b9c0c59
TZ
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
eccdfe2d 3192static LIST_HEAD(script_descs);
4b9c0c59
TZ
3193
3194static struct script_desc *script_desc__new(const char *name)
3195{
3196 struct script_desc *s = zalloc(sizeof(*s));
3197
b5b87312 3198 if (s != NULL && name)
4b9c0c59
TZ
3199 s->name = strdup(name);
3200
3201 return s;
3202}
3203
3204static void script_desc__delete(struct script_desc *s)
3205{
74cf249d
ACM
3206 zfree(&s->name);
3207 zfree(&s->half_liner);
3208 zfree(&s->args);
4b9c0c59
TZ
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)
2ec5cab6 3236 return NULL;
4b9c0c59
TZ
3237
3238 script_desc__add(s);
3239
3240 return s;
4b9c0c59
TZ
3241}
3242
965bb6be 3243static const char *ends_with(const char *str, const char *suffix)
4b9c0c59
TZ
3244{
3245 size_t suffix_len = strlen(suffix);
965bb6be 3246 const char *p = str;
4b9c0c59
TZ
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
4b9c0c59
TZ
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)) {
32858480 3267 p = skip_spaces(line);
4b9c0c59
TZ
3268 if (strlen(p) == 0)
3269 continue;
3270 if (*p != '#')
3271 continue;
3272 p++;
3273 if (strlen(p) && *p == '!')
3274 continue;
3275
32858480 3276 p = skip_spaces(p);
4b9c0c59
TZ
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:");
32858480 3282 desc->half_liner = strdup(skip_spaces(p));
4b9c0c59
TZ
3283 continue;
3284 }
3285
3286 if (!strncmp(p, "args:", strlen("args:"))) {
3287 p += strlen("args:");
32858480 3288 desc->args = strdup(skip_spaces(p));
4b9c0c59
TZ
3289 continue;
3290 }
3291 }
3292
3293 fclose(fp);
3294
3295 return 0;
3296}
3297
38efb539
RR
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
1d037ca1
IT
3316static int list_available_scripts(const struct option *opt __maybe_unused,
3317 const char *s __maybe_unused,
3318 int unset __maybe_unused)
4b9c0c59 3319{
a5e8e825 3320 struct dirent *script_dirent, *lang_dirent;
e590e46b 3321 char *buf, *scripts_path, *script_path, *lang_path, *first_half;
4b9c0c59 3322 DIR *scripts_dir, *lang_dir;
4b9c0c59 3323 struct script_desc *desc;
4b9c0c59 3324 char *script_root;
4b9c0c59 3325
e590e46b
IR
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
46113a54 3336 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
4b9c0c59
TZ
3337
3338 scripts_dir = opendir(scripts_path);
88ded4d8
HK
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);
e590e46b 3344 free(buf);
88ded4d8
HK
3345 exit(-1);
3346 }
4b9c0c59 3347
a5e8e825 3348 for_each_lang(scripts_path, scripts_dir, lang_dirent) {
77f18153
JO
3349 scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
3350 lang_dirent->d_name);
4b9c0c59
TZ
3351 lang_dir = opendir(lang_path);
3352 if (!lang_dir)
3353 continue;
3354
a5e8e825
ACM
3355 for_each_script(lang_path, lang_dir, script_dirent) {
3356 script_root = get_script_root(script_dirent, REPORT_SUFFIX);
38efb539 3357 if (script_root) {
4b9c0c59 3358 desc = script_desc__findnew(script_root);
77f18153
JO
3359 scnprintf(script_path, MAXPATHLEN, "%s/%s",
3360 lang_path, script_dirent->d_name);
4b9c0c59 3361 read_script_info(desc, script_path);
38efb539 3362 free(script_root);
4b9c0c59 3363 }
4b9c0c59
TZ
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
e590e46b 3375 free(buf);
4b9c0c59
TZ
3376 exit(0);
3377}
3378
3d032a25
AH
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
3875294f
TZ
3407static char *get_script_path(const char *script_root, const char *suffix)
3408{
a5e8e825 3409 struct dirent *script_dirent, *lang_dirent;
3875294f
TZ
3410 char scripts_path[MAXPATHLEN];
3411 char script_path[MAXPATHLEN];
3412 DIR *scripts_dir, *lang_dir;
3413 char lang_path[MAXPATHLEN];
38efb539 3414 char *__script_root;
3875294f 3415
46113a54 3416 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
3875294f
TZ
3417
3418 scripts_dir = opendir(scripts_path);
3419 if (!scripts_dir)
3420 return NULL;
3421
a5e8e825 3422 for_each_lang(scripts_path, scripts_dir, lang_dirent) {
77f18153
JO
3423 scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
3424 lang_dirent->d_name);
3875294f
TZ
3425 lang_dir = opendir(lang_path);
3426 if (!lang_dir)
3427 continue;
3428
a5e8e825
ACM
3429 for_each_script(lang_path, lang_dir, script_dirent) {
3430 __script_root = get_script_root(script_dirent, suffix);
38efb539
RR
3431 if (__script_root && !strcmp(script_root, __script_root)) {
3432 free(__script_root);
946ef2a2 3433 closedir(scripts_dir);
77f18153
JO
3434 scnprintf(script_path, MAXPATHLEN, "%s/%s",
3435 lang_path, script_dirent->d_name);
27486a85 3436 closedir(lang_dir);
38efb539 3437 return strdup(script_path);
3875294f
TZ
3438 }
3439 free(__script_root);
3440 }
946ef2a2 3441 closedir(lang_dir);
3875294f 3442 }
946ef2a2 3443 closedir(scripts_dir);
3875294f 3444
38efb539 3445 return NULL;
3875294f
TZ
3446}
3447
b5b87312
TZ
3448static bool is_top_script(const char *script_path)
3449{
8524711d 3450 return ends_with(script_path, "top") != NULL;
b5b87312
TZ
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
69b6470e
ACM
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);
5f9c39dc 3489
69b6470e
ACM
3490 system_wide = (argc == 0);
3491
3492 return 0;
3493}
3494
7322d6c9
JO
3495static void script__setup_sample_type(struct perf_script *script)
3496{
3497 struct perf_session *session = script->session;
b3c2cc2b 3498 u64 sample_type = evlist__combined_sample_type(session->evlist);
7322d6c9 3499
aa8db3e4 3500 callchain_param_setup(sample_type, perf_env__arch(session->machines.host.env));
680d125c
KL
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 }
7322d6c9
JO
3507}
3508
89f1688a
JO
3509static int process_stat_round_event(struct perf_session *session,
3510 union perf_event *event)
e099eba8 3511{
72932371 3512 struct perf_record_stat_round *round = &event->stat_round;
32dcd021 3513 struct evsel *counter;
e099eba8 3514
e5cadb93 3515 evlist__for_each_entry(session->evlist, counter) {
e099eba8
JO
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
89f1688a
JO
3524static int process_stat_config_event(struct perf_session *session __maybe_unused,
3525 union perf_event *event)
91a2c3d5
JO
3526{
3527 perf_event__read_stat_config(&stat_config, &event->stat_config);
2fe65759
SD
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
91a2c3d5
JO
3535 return 0;
3536}
3537
cfc8874a
JO
3538static int set_maps(struct perf_script *script)
3539{
63503dba 3540 struct evlist *evlist = script->session->evlist;
cfc8874a
JO
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
453fa030 3548 perf_evlist__set_maps(&evlist->core, script->cpus, script->threads);
cfc8874a 3549
1f297a6e 3550 if (evlist__alloc_stats(&stat_config, evlist, /*alloc_raw=*/true))
cfc8874a
JO
3551 return -ENOMEM;
3552
3553 script->allocated = true;
3554 return 0;
3555}
3556
3557static
89f1688a
JO
3558int process_thread_map_event(struct perf_session *session,
3559 union perf_event *event)
cfc8874a 3560{
30f29bae 3561 const struct perf_tool *tool = session->tool;
cfc8874a
JO
3562 struct perf_script *script = container_of(tool, struct perf_script, tool);
3563
52f28b7b
AH
3564 if (dump_trace)
3565 perf_event__fprintf_thread_map(event, stdout);
3566
cfc8874a
JO
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
89f1688a
JO
3580int process_cpu_map_event(struct perf_session *session,
3581 union perf_event *event)
cfc8874a 3582{
30f29bae 3583 const struct perf_tool *tool = session->tool;
cfc8874a
JO
3584 struct perf_script *script = container_of(tool, struct perf_script, tool);
3585
52f28b7b
AH
3586 if (dump_trace)
3587 perf_event__fprintf_cpu_map(event, stdout);
3588
cfc8874a
JO
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
89f1688a
JO
3601static int process_feature_event(struct perf_session *session,
3602 union perf_event *event)
92ead7ee
RB
3603{
3604 if (event->feat.feat_id < HEADER_LAST_FEATURE)
89f1688a 3605 return perf_event__process_feature(session, event);
92ead7ee
RB
3606 return 0;
3607}
3608
fa48c892 3609#ifdef HAVE_AUXTRACE_SUPPORT
89f1688a
JO
3610static int perf_script__process_auxtrace_info(struct perf_session *session,
3611 union perf_event *event)
fa48c892 3612{
89f1688a 3613 int ret = perf_event__process_auxtrace_info(session, event);
fa48c892
ACM
3614
3615 if (ret == 0) {
30f29bae 3616 const struct perf_tool *tool = session->tool;
fa48c892
ACM
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
b585ebdb 3628static int parse_insn_trace(const struct option *opt __maybe_unused,
6750ba4b 3629 const char *str, int unset __maybe_unused)
b585ebdb 3630{
6750ba4b
CD
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
d4a98b45 3647 itrace_parse_synth_opts(opt, "i0nse", 0);
52bab886 3648 symbol_conf.nanosecs = true;
b585ebdb
AK
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{
8c3e05c8
AK
3656 if (isatty(1))
3657 force_pager("xed -F insn: -A -64 | less");
3658 else
3659 force_pager("xed -F insn: -A -64");
b585ebdb
AK
3660 return 0;
3661}
3662
d1b1552e
AK
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);
52bab886 3669 symbol_conf.nanosecs = true;
1c492422 3670 symbol_conf.pad_output_len_dso = 50;
d1b1552e
AK
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);
52bab886 3680 symbol_conf.nanosecs = true;
d1b1552e
AK
3681 return 0;
3682}
3683
b0ad8ea6 3684int cmd_script(int argc, const char **argv)
69b6470e
ACM
3685{
3686 bool show_full_info = false;
e90debdd
JO
3687 bool header = false;
3688 bool header_only = false;
6cc870f0 3689 bool script_started = false;
57190e38 3690 bool unsorted_dump = false;
69b6470e
ACM
3691 char *rec_script_path = NULL;
3692 char *rep_script_path = NULL;
3693 struct perf_session *session;
4eb06815
AK
3694 struct itrace_synth_opts itrace_synth_opts = {
3695 .set = false,
3696 .default_no_sample = true,
3697 };
3ab481a1 3698 struct utsname uts;
69b6470e 3699 char *script_path = NULL;
291961fc 3700 const char *dlfilter_file = NULL;
69b6470e 3701 const char **__argv;
6cc870f0 3702 int i, j, err = 0;
2fa28ccb 3703 struct perf_script script = {};
8ceb41d7 3704 struct perf_data data = {
06af0f2c
YS
3705 .mode = PERF_DATA_MODE_READ,
3706 };
69b6470e 3707 const struct option options[] = {
5f9c39dc
FW
3708 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
3709 "dump raw trace in ASCII"),
57190e38
AH
3710 OPT_BOOLEAN(0, "dump-unsorted-raw-trace", &unsorted_dump,
3711 "dump unsorted raw trace in ASCII"),
c0555642 3712 OPT_INCR('v', "verbose", &verbose,
69b6470e 3713 "be more verbose (show symbol address, etc)"),
4b9c0c59 3714 OPT_BOOLEAN('L', "Latency", &latency_format,
cda48461 3715 "show latency attributes (irqs/preemption disabled, etc)"),
4b9c0c59
TZ
3716 OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
3717 list_available_scripts),
638e2b99
AH
3718 OPT_CALLBACK_NOOPT(0, "list-dlfilters", NULL, NULL, "list available dlfilters",
3719 list_available_dlfilters),
956ffd02
TZ
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",
133dc4c3 3724 "generate perf-script.xx script in specified language"),
291961fc 3725 OPT_STRING(0, "dlfilter", &dlfilter_file, "file", "filter .so file name"),
3d032a25
AH
3726 OPT_CALLBACK(0, "dlarg", NULL, "argument", "filter argument",
3727 add_dlarg),
69b6470e 3728 OPT_STRING('i', "input", &input_name, "file", "input file name"),
ffabd99e
FW
3729 OPT_BOOLEAN('d', "debug-mode", &debug_mode,
3730 "do various checks like samples ordering and lost events"),
e90debdd
JO
3731 OPT_BOOLEAN(0, "header", &header, "Show data header."),
3732 OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),
c0230b2b
DA
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"),
a7066709
HK
3739 OPT_CALLBACK(0, "symfs", NULL, "directory",
3740 "Look for files with symbols relative to this directory",
3741 symbol__config_symfs),
06af0f2c 3742 OPT_CALLBACK('F', "fields", NULL, "str",
a978f2ab 3743 "comma separated output fields prepend with 'type:'. "
36ce5651 3744 "+field to add and -field to remove."
1405720d 3745 "Valid types: hw,sw,trace,raw,synth. "
9a13ee45 3746 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,dsoff,"
10e9cec9 3747 "addr,symoff,srcline,period,iregs,uregs,brstack,"
d7931070 3748 "brstacksym,flags,data_src,weight,bpf-output,brstackinsn,"
d8120446 3749 "brstackinsnlen,brstackdisasm,brstackoff,callindent,insn,disasm,insnlen,synth,"
d7931070 3750 "phys_addr,metric,misc,srccode,ipc,tod,data_page_size,"
6f9d8d1d
KL
3751 "code_page_size,ins_lat,machine_pid,vcpu,cgroup,retire_lat,"
3752 "brcntr",
48d02a1d 3753 parse_output_fields),
317df650 3754 OPT_BOOLEAN('a', "all-cpus", &system_wide,
69b6470e 3755 "system-wide collection from all CPUs"),
4b799a9b
JY
3756 OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
3757 "only consider symbols in these DSOs"),
36385be5
FT
3758 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
3759 "only consider these symbols"),
61d9fc44
JY
3760 OPT_INTEGER(0, "addr-range", &symbol_conf.addr_range,
3761 "Use with -S to list traced records within address range"),
6750ba4b 3762 OPT_CALLBACK_OPTARG(0, "insn-trace", &itrace_synth_opts, NULL, "raw|disasm",
b585ebdb
AK
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),
d1b1552e 3766 OPT_CALLBACK_OPTARG(0, "call-trace", &itrace_synth_opts, NULL, NULL,
ae4e4a0b 3767 "Decode calls from itrace", parse_call_trace),
d1b1552e
AK
3768 OPT_CALLBACK_OPTARG(0, "call-ret-trace", &itrace_synth_opts, NULL, NULL,
3769 "Decode calls and returns from itrace", parse_callret_trace),
99f753f0
AK
3770 OPT_STRING(0, "graph-function", &symbol_conf.graph_function, "symbol[,symbol...]",
3771 "Only print symbols and callees with --call-trace/--call-ret-trace"),
64eff7d9
DA
3772 OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]",
3773 "Stop display of callgraph at these symbols"),
c8e66720 3774 OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
e7984b7b
DA
3775 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
3776 "only display events for these comms"),
e03eaa40
DA
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"),
6125cc8d
ACM
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. "
4cb93446 3784 "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
90b10f47 3785 OPT_BOOLEAN(0, "reltime", &reltime, "Show time stamps relative to start"),
26567ed7 3786 OPT_BOOLEAN(0, "deltatime", &deltatime, "Show time stamps relative to previous event"),
fbe96f29
SE
3787 OPT_BOOLEAN('I', "show-info", &show_full_info,
3788 "display extended information from perf.data file"),
0bc8d205
AN
3789 OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
3790 "Show the path of [kernel.kallsyms]"),
ad7ebb9a
NK
3791 OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events,
3792 "Show the fork/comm/exit events"),
ba1ddf42
NK
3793 OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
3794 "Show the mmap events"),
7c14898b
AH
3795 OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
3796 "Show context switch events (if recorded)"),
96a44bbc
HB
3797 OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
3798 "Show namespace events (if recorded)"),
160d4af9
NK
3799 OPT_BOOLEAN('\0', "show-cgroup-events", &script.show_cgroup_events,
3800 "Show cgroup events (if recorded)"),
3d7c27b6
JO
3801 OPT_BOOLEAN('\0', "show-lost-events", &script.show_lost_events,
3802 "Show lost events (if recorded)"),
3233b37a
JO
3803 OPT_BOOLEAN('\0', "show-round-events", &script.show_round_events,
3804 "Show round events (if recorded)"),
490c8cc9
JO
3805 OPT_BOOLEAN('\0', "show-bpf-events", &script.show_bpf_events,
3806 "Show bpf related events (if recorded)"),
92ecf3a6
AH
3807 OPT_BOOLEAN('\0', "show-text-poke-events", &script.show_text_poke_events,
3808 "Show text poke related events (if recorded)"),
a14390fd
ACM
3809 OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
3810 "Dump trace output to files named by the monitored events"),
be3d466c 3811 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
48d02a1d
AK
3812 OPT_INTEGER(0, "max-blocks", &max_blocks,
3813 "Maximum number of code blocks to dump with brstackinsn"),
52bab886 3814 OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs,
83e19860 3815 "Use 9 decimal places when displaying time"),
7a680eb9 3816 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
c12e039d 3817 "Instruction Tracing options\n" ITRACE_HELP,
7a680eb9 3818 itrace_parse_synth_opts),
a9710ba0
AK
3819 OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
3820 "Show full source file name path for source lines"),
77e0070d
MD
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"),
e6b56ae7
ML
3825 OPT_STRING(0, "addr2line", &symbol_conf.addr2line_path, "path",
3826 "addr2line binary to use for line numbers"),
a91f4c47
DA
3827 OPT_STRING(0, "time", &script.time_str, "str",
3828 "Time span of interest (start,stop)"),
325fbff5
NK
3829 OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
3830 "Show inline function"),
15a108af
ACM
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"),
5b208144
AH
3840 OPT_BOOLEAN(0, "guest-code", &symbol_conf.guest_code,
3841 "Guest code can be found in hypervisor process"),
680d125c
KL
3842 OPT_BOOLEAN('\0', "stitch-lbr", &script.stitch_lbr,
3843 "Enable LBR callgraph stitching approach"),
add3a719 3844 OPTS_EVSWITCH(&script.evswitch),
1909629f 3845 OPT_END()
69b6470e 3846 };
40cae2b7
YS
3847 const char * const script_subcommands[] = { "record", "report", NULL };
3848 const char *script_usage[] = {
69b6470e
ACM
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 };
3875294f 3856
0a7c74ea
ACM
3857 perf_set_singlethreaded();
3858
b5b87312
TZ
3859 setup_scripting();
3860
40cae2b7 3861 argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
b5b87312
TZ
3862 PARSE_OPT_STOP_AT_NON_OPTION);
3863
15a108af
ACM
3864 if (symbol_conf.guestmount ||
3865 symbol_conf.default_guest_vmlinux_name ||
3866 symbol_conf.default_guest_kallsyms ||
5b208144
AH
3867 symbol_conf.default_guest_modules ||
3868 symbol_conf.guest_code) {
15a108af
ACM
3869 /*
3870 * Enable guest sample processing.
3871 */
3872 perf_guest = true;
3873 }
3874
2d4f2799
JO
3875 data.path = input_name;
3876 data.force = symbol_conf.force;
f5fc1412 3877
2fa28ccb 3878 if (unsorted_dump)
57190e38 3879 dump_trace = true;
57190e38 3880
7cc72553
JC
3881 if (symbol__validate_sym_arguments())
3882 return -1;
3883
ae0f4eb3 3884 if (argc > 1 && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
b5b87312
TZ
3885 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
3886 if (!rec_script_path)
b0ad8ea6 3887 return cmd_record(argc, argv);
3875294f
TZ
3888 }
3889
ae0f4eb3 3890 if (argc > 1 && strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
b5b87312
TZ
3891 rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
3892 if (!rep_script_path) {
3875294f 3893 fprintf(stderr,
b5b87312 3894 "Please specify a valid report script"
133dc4c3 3895 "(see 'perf script -l' for listing)\n");
3875294f
TZ
3896 return -1;
3897 }
3875294f
TZ
3898 }
3899
26567ed7
HPP
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
1c5c25b3 3907 if ((itrace_synth_opts.callchain || itrace_synth_opts.add_callchain) &&
3c5b645f
AH
3908 itrace_synth_opts.callchain_sz > scripting_max_stack)
3909 scripting_max_stack = itrace_synth_opts.callchain_sz;
3910
44e668c6 3911 /* make sure PERF_EXEC_PATH is set for scripts */
46113a54 3912 set_argv_exec_path(get_argv_exec_path());
44e668c6 3913
b5b87312 3914 if (argc && !script_name && !rec_script_path && !rep_script_path) {
a0cccc2e 3915 int live_pipe[2];
b5b87312 3916 int rep_args;
a0cccc2e
TZ
3917 pid_t pid;
3918
b5b87312
TZ
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) {
6ea4b5db
AH
3923 script_name = find_script(argv[0]);
3924 if (script_name) {
3925 argc -= 1;
3926 argv += 1;
3927 goto script_found;
3928 }
c7118369
NK
3929 usage_with_options_msg(script_usage, options,
3930 "Couldn't find script `%s'\n\n See perf"
133dc4c3 3931 " script -l for available scripts.\n", argv[0]);
a0cccc2e
TZ
3932 }
3933
b5b87312
TZ
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) {
c7118369
NK
3942 usage_with_options_msg(script_usage, options,
3943 "`%s' script requires options."
133dc4c3 3944 "\n\n See perf script -l for available "
b5b87312 3945 "scripts and options.\n", argv[0]);
b5b87312 3946 }
a0cccc2e
TZ
3947 }
3948
3949 if (pipe(live_pipe) < 0) {
3950 perror("failed to create pipe");
d54b1a9e 3951 return -1;
a0cccc2e
TZ
3952 }
3953
3954 pid = fork();
3955 if (pid < 0) {
3956 perror("failed to fork");
d54b1a9e 3957 return -1;
a0cccc2e
TZ
3958 }
3959
3960 if (!pid) {
b5b87312
TZ
3961 j = 0;
3962
a0cccc2e
TZ
3963 dup2(live_pipe[1], 1);
3964 close(live_pipe[0]);
3965
317df650
RR
3966 if (is_top_script(argv[0])) {
3967 system_wide = true;
3968 } else if (!system_wide) {
d54b1a9e
DA
3969 if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
3970 err = -1;
3971 goto out;
3972 }
317df650 3973 }
b5b87312
TZ
3974
3975 __argv = malloc((argc + 6) * sizeof(const char *));
d54b1a9e
DA
3976 if (!__argv) {
3977 pr_err("malloc failed\n");
3978 err = -ENOMEM;
3979 goto out;
3980 }
e8719adf 3981
b5b87312
TZ
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;
a0cccc2e
TZ
3992
3993 execvp("/bin/sh", (char **)__argv);
e8719adf 3994 free(__argv);
a0cccc2e
TZ
3995 exit(-1);
3996 }
3997
3998 dup2(live_pipe[0], 0);
3999 close(live_pipe[1]);
4000
b5b87312 4001 __argv = malloc((argc + 4) * sizeof(const char *));
d54b1a9e
DA
4002 if (!__argv) {
4003 pr_err("malloc failed\n");
4004 err = -ENOMEM;
4005 goto out;
4006 }
4007
b5b87312
TZ
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;
a0cccc2e
TZ
4016
4017 execvp("/bin/sh", (char **)__argv);
e8719adf 4018 free(__argv);
a0cccc2e
TZ
4019 exit(-1);
4020 }
6ea4b5db 4021script_found:
b5b87312
TZ
4022 if (rec_script_path)
4023 script_path = rec_script_path;
4024 if (rep_script_path)
4025 script_path = rep_script_path;
34c86ea9 4026
b5b87312 4027 if (script_path) {
b5b87312 4028 j = 0;
3875294f 4029
317df650
RR
4030 if (!rec_script_path)
4031 system_wide = false;
d54b1a9e
DA
4032 else if (!system_wide) {
4033 if (have_cmd(argc - 1, &argv[1]) != 0) {
4034 err = -1;
4035 goto out;
4036 }
4037 }
34c86ea9 4038
b5b87312 4039 __argv = malloc((argc + 2) * sizeof(const char *));
d54b1a9e
DA
4040 if (!__argv) {
4041 pr_err("malloc failed\n");
4042 err = -ENOMEM;
4043 goto out;
4044 }
4045
34c86ea9
TZ
4046 __argv[j++] = "/bin/sh";
4047 __argv[j++] = script_path;
4048 if (system_wide)
4049 __argv[j++] = "-a";
b5b87312 4050 for (i = 2; i < argc; i++)
34c86ea9
TZ
4051 __argv[j++] = argv[i];
4052 __argv[j++] = NULL;
3875294f
TZ
4053
4054 execvp("/bin/sh", (char **)__argv);
e8719adf 4055 free(__argv);
3875294f
TZ
4056 exit(-1);
4057 }
956ffd02 4058
291961fc 4059 if (dlfilter_file) {
3d032a25 4060 dlfilter = dlfilter__new(dlfilter_file, dlargc, dlargv);
291961fc
AH
4061 if (!dlfilter)
4062 return -1;
4063 }
4064
c1c9b969 4065 if (!script_name) {
cf4fee50 4066 setup_pager();
c1c9b969
MW
4067 use_browser = 0;
4068 }
5f9c39dc 4069
2fa28ccb
IR
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;
2681bd85 4098 session = perf_session__new(&data, &script.tool);
6ef81c55
MI
4099 if (IS_ERR(session))
4100 return PTR_ERR(session);
d8f66248 4101
e90debdd 4102 if (header || header_only) {
114f709e 4103 script.tool.show_feat_hdr = SHOW_FEAT_HEADER;
e90debdd
JO
4104 perf_session__fprintf_info(session, stdout, show_full_info);
4105 if (header_only)
6cc870f0 4106 goto out_delete;
e90debdd 4107 }
114f709e
DCC
4108 if (show_full_info)
4109 script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
e90debdd 4110
0a7e6d1b 4111 if (symbol__init(&session->header.env) < 0)
38520dc3
NK
4112 goto out_delete;
4113
3ab481a1 4114 uname(&uts);
29c77550 4115 if (data.is_pipe) { /* Assume pipe_mode indicates native_arch */
3ab481a1 4116 native_arch = true;
29c77550
SL
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 }
3ab481a1 4124
6f3e5eda 4125 script.session = session;
7322d6c9 4126 script__setup_sample_type(&script);
6f3e5eda 4127
99f753f0
AK
4128 if ((output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT) ||
4129 symbol_conf.graph_function)
e216708d
AH
4130 itrace_synth_opts.thread_stack = true;
4131
7a680eb9
AH
4132 session->itrace_synth_opts = &itrace_synth_opts;
4133
5d67be97 4134 if (cpu_list) {
6cc870f0
NK
4135 err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
4136 if (err < 0)
4137 goto out_delete;
644e0840 4138 itrace_synth_opts.cpu_bitmap = cpu_bitmap;
5d67be97
AB
4139 }
4140
1424dc96 4141 if (!no_callchain)
c0230b2b
DA
4142 symbol_conf.use_callchain = true;
4143 else
4144 symbol_conf.use_callchain = false;
4145
378ef0f5 4146#ifdef HAVE_LIBTRACEEVENT
9ee67421 4147 if (session->tevent.pevent &&
ece2a4f4
TSV
4148 tep_set_function_resolver(session->tevent.pevent,
4149 machine__resolve_kernel_addr,
4150 &session->machines.host) < 0) {
ccb3a829 4151 pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
db49bc15
CJ
4152 err = -1;
4153 goto out_delete;
ccb3a829 4154 }
378ef0f5 4155#endif
956ffd02
TZ
4156 if (generate_script_lang) {
4157 struct stat perf_stat;
745f43e3
DA
4158 int input;
4159
2c9e45f7 4160 if (output_set_by_user()) {
745f43e3
DA
4161 fprintf(stderr,
4162 "custom fields not supported for generated scripts");
6cc870f0
NK
4163 err = -EINVAL;
4164 goto out_delete;
745f43e3 4165 }
956ffd02 4166
2d4f2799 4167 input = open(data.path, O_RDONLY); /* input_name */
956ffd02 4168 if (input < 0) {
6cc870f0 4169 err = -errno;
956ffd02 4170 perror("failed to open file");
6cc870f0 4171 goto out_delete;
956ffd02
TZ
4172 }
4173
4174 err = fstat(input, &perf_stat);
4175 if (err < 0) {
4176 perror("failed to stat file");
6cc870f0 4177 goto out_delete;
956ffd02
TZ
4178 }
4179
4180 if (!perf_stat.st_size) {
4181 fprintf(stderr, "zero-sized file, nothing to do!\n");
6cc870f0 4182 goto out_delete;
956ffd02
TZ
4183 }
4184
4185 scripting_ops = script_spec__lookup(generate_script_lang);
4186 if (!scripting_ops) {
4187 fprintf(stderr, "invalid language specifier");
6cc870f0
NK
4188 err = -ENOENT;
4189 goto out_delete;
956ffd02 4190 }
378ef0f5 4191#ifdef HAVE_LIBTRACEEVENT
29f5ffd3 4192 err = scripting_ops->generate_script(session->tevent.pevent,
da378962 4193 "perf-script");
378ef0f5
IR
4194#else
4195 err = scripting_ops->generate_script(NULL, "perf-script");
4196#endif
6cc870f0 4197 goto out_delete;
956ffd02
TZ
4198 }
4199
291961fc
AH
4200 err = dlfilter__start(dlfilter, session);
4201 if (err)
4202 goto out_delete;
4203
956ffd02 4204 if (script_name) {
67e50ce0 4205 err = scripting_ops->start_script(script_name, argc, argv, session);
956ffd02 4206 if (err)
6cc870f0 4207 goto out_delete;
133dc4c3 4208 pr_debug("perf script started with script %s\n\n", script_name);
6cc870f0 4209 script_started = true;
956ffd02
TZ
4210 }
4211
9cbdb702
DA
4212
4213 err = perf_session__check_output_opt(session);
4214 if (err < 0)
6cc870f0 4215 goto out_delete;
9cbdb702 4216
284c4e18 4217 if (script.time_str) {
b3509b6e 4218 err = perf_time__parse_for_ranges_reltime(script.time_str, session,
284c4e18
JY
4219 &script.ptime_range,
4220 &script.range_size,
b3509b6e
AK
4221 &script.range_num,
4222 reltime);
284c4e18 4223 if (err < 0)
2ab046cd 4224 goto out_delete;
400ae981
AH
4225
4226 itrace_synth_opts__set_time_range(&itrace_synth_opts,
4227 script.ptime_range,
4228 script.range_num);
a91f4c47
DA
4229 }
4230
124e02be
ACM
4231 err = evswitch__init(&script.evswitch, session->evlist, stderr);
4232 if (err)
4233 goto out_delete;
dd41f660 4234
b13b04d9
MW
4235 if (zstd_init(&(session->zstd_data), 0) < 0)
4236 pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");
4237
6f3e5eda 4238 err = __cmd_script(&script);
956ffd02 4239
d445dd2a
AH
4240 flush_scripting();
4241
0bdfbd04
AH
4242 if (verbose > 2 || debug_kmaps)
4243 perf_session__dump_kmaps(session);
4244
6cc870f0 4245out_delete:
400ae981
AH
4246 if (script.ptime_range) {
4247 itrace_synth_opts__clear_time_range(&itrace_synth_opts);
284c4e18 4248 zfree(&script.ptime_range);
400ae981 4249 }
cc2ef584 4250
1b1f57cf 4251 zstd_fini(&(session->zstd_data));
53f5e908 4252 evlist__free_stats(session->evlist);
d8f66248 4253 perf_session__delete(session);
faf3ac30 4254 perf_script__exit(&script);
6cc870f0
NK
4255
4256 if (script_started)
4257 cleanup_scripting();
291961fc 4258 dlfilter__cleanup(dlfilter);
3d032a25 4259 free_dlarg();
956ffd02
TZ
4260out:
4261 return err;
5f9c39dc 4262}