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