linux/tools/perf/builtin-script.c
<<
>>
Prefs
   1#include "builtin.h"
   2
   3#include "perf.h"
   4#include "util/cache.h"
   5#include "util/debug.h"
   6#include <subcmd/exec-cmd.h>
   7#include "util/header.h"
   8#include <subcmd/parse-options.h>
   9#include "util/perf_regs.h"
  10#include "util/session.h"
  11#include "util/tool.h"
  12#include "util/symbol.h"
  13#include "util/thread.h"
  14#include "util/trace-event.h"
  15#include "util/util.h"
  16#include "util/evlist.h"
  17#include "util/evsel.h"
  18#include "util/sort.h"
  19#include "util/data.h"
  20#include "util/auxtrace.h"
  21#include "util/cpumap.h"
  22#include "util/thread_map.h"
  23#include "util/stat.h"
  24#include "util/string2.h"
  25#include "util/thread-stack.h"
  26#include "util/time-utils.h"
  27#include "print_binary.h"
  28#include <linux/bitmap.h>
  29#include <linux/kernel.h>
  30#include <linux/stringify.h>
  31#include <linux/time64.h>
  32#include "asm/bug.h"
  33#include "util/mem-events.h"
  34#include "util/dump-insn.h"
  35#include <dirent.h>
  36#include <errno.h>
  37#include <inttypes.h>
  38#include <signal.h>
  39#include <sys/param.h>
  40#include <sys/types.h>
  41#include <sys/stat.h>
  42#include <unistd.h>
  43
  44#include "sane_ctype.h"
  45
  46static char const               *script_name;
  47static char const               *generate_script_lang;
  48static bool                     debug_mode;
  49static u64                      last_timestamp;
  50static u64                      nr_unordered;
  51static bool                     no_callchain;
  52static bool                     latency_format;
  53static bool                     system_wide;
  54static bool                     print_flags;
  55static bool                     nanosecs;
  56static const char               *cpu_list;
  57static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
  58static struct perf_stat_config  stat_config;
  59static int                      max_blocks;
  60
  61unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
  62
  63enum perf_output_field {
  64        PERF_OUTPUT_COMM            = 1U << 0,
  65        PERF_OUTPUT_TID             = 1U << 1,
  66        PERF_OUTPUT_PID             = 1U << 2,
  67        PERF_OUTPUT_TIME            = 1U << 3,
  68        PERF_OUTPUT_CPU             = 1U << 4,
  69        PERF_OUTPUT_EVNAME          = 1U << 5,
  70        PERF_OUTPUT_TRACE           = 1U << 6,
  71        PERF_OUTPUT_IP              = 1U << 7,
  72        PERF_OUTPUT_SYM             = 1U << 8,
  73        PERF_OUTPUT_DSO             = 1U << 9,
  74        PERF_OUTPUT_ADDR            = 1U << 10,
  75        PERF_OUTPUT_SYMOFFSET       = 1U << 11,
  76        PERF_OUTPUT_SRCLINE         = 1U << 12,
  77        PERF_OUTPUT_PERIOD          = 1U << 13,
  78        PERF_OUTPUT_IREGS           = 1U << 14,
  79        PERF_OUTPUT_BRSTACK         = 1U << 15,
  80        PERF_OUTPUT_BRSTACKSYM      = 1U << 16,
  81        PERF_OUTPUT_DATA_SRC        = 1U << 17,
  82        PERF_OUTPUT_WEIGHT          = 1U << 18,
  83        PERF_OUTPUT_BPF_OUTPUT      = 1U << 19,
  84        PERF_OUTPUT_CALLINDENT      = 1U << 20,
  85        PERF_OUTPUT_INSN            = 1U << 21,
  86        PERF_OUTPUT_INSNLEN         = 1U << 22,
  87        PERF_OUTPUT_BRSTACKINSN     = 1U << 23,
  88        PERF_OUTPUT_BRSTACKOFF      = 1U << 24,
  89        PERF_OUTPUT_SYNTH           = 1U << 25,
  90};
  91
  92struct output_option {
  93        const char *str;
  94        enum perf_output_field field;
  95} all_output_options[] = {
  96        {.str = "comm",  .field = PERF_OUTPUT_COMM},
  97        {.str = "tid",   .field = PERF_OUTPUT_TID},
  98        {.str = "pid",   .field = PERF_OUTPUT_PID},
  99        {.str = "time",  .field = PERF_OUTPUT_TIME},
 100        {.str = "cpu",   .field = PERF_OUTPUT_CPU},
 101        {.str = "event", .field = PERF_OUTPUT_EVNAME},
 102        {.str = "trace", .field = PERF_OUTPUT_TRACE},
 103        {.str = "ip",    .field = PERF_OUTPUT_IP},
 104        {.str = "sym",   .field = PERF_OUTPUT_SYM},
 105        {.str = "dso",   .field = PERF_OUTPUT_DSO},
 106        {.str = "addr",  .field = PERF_OUTPUT_ADDR},
 107        {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
 108        {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
 109        {.str = "period", .field = PERF_OUTPUT_PERIOD},
 110        {.str = "iregs", .field = PERF_OUTPUT_IREGS},
 111        {.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
 112        {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
 113        {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},
 114        {.str = "weight",   .field = PERF_OUTPUT_WEIGHT},
 115        {.str = "bpf-output",   .field = PERF_OUTPUT_BPF_OUTPUT},
 116        {.str = "callindent", .field = PERF_OUTPUT_CALLINDENT},
 117        {.str = "insn", .field = PERF_OUTPUT_INSN},
 118        {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},
 119        {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
 120        {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
 121        {.str = "synth", .field = PERF_OUTPUT_SYNTH},
 122};
 123
 124enum {
 125        OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,
 126        OUTPUT_TYPE_MAX
 127};
 128
 129/* default set to maintain compatibility with current format */
 130static struct {
 131        bool user_set;
 132        bool wildcard_set;
 133        unsigned int print_ip_opts;
 134        u64 fields;
 135        u64 invalid_fields;
 136} output[OUTPUT_TYPE_MAX] = {
 137
 138        [PERF_TYPE_HARDWARE] = {
 139                .user_set = false,
 140
 141                .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
 142                              PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
 143                              PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
 144                              PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
 145                              PERF_OUTPUT_PERIOD,
 146
 147                .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
 148        },
 149
 150        [PERF_TYPE_SOFTWARE] = {
 151                .user_set = false,
 152
 153                .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
 154                              PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
 155                              PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
 156                              PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
 157                              PERF_OUTPUT_PERIOD | PERF_OUTPUT_BPF_OUTPUT,
 158
 159                .invalid_fields = PERF_OUTPUT_TRACE,
 160        },
 161
 162        [PERF_TYPE_TRACEPOINT] = {
 163                .user_set = false,
 164
 165                .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
 166                                  PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
 167                                  PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE
 168        },
 169
 170        [PERF_TYPE_RAW] = {
 171                .user_set = false,
 172
 173                .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
 174                              PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
 175                              PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
 176                              PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
 177                              PERF_OUTPUT_PERIOD |  PERF_OUTPUT_ADDR |
 178                              PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT,
 179
 180                .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
 181        },
 182
 183        [PERF_TYPE_BREAKPOINT] = {
 184                .user_set = false,
 185
 186                .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
 187                              PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
 188                              PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
 189                              PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
 190                              PERF_OUTPUT_PERIOD,
 191
 192                .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
 193        },
 194
 195        [OUTPUT_TYPE_SYNTH] = {
 196                .user_set = false,
 197
 198                .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
 199                              PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
 200                              PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
 201                              PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
 202                              PERF_OUTPUT_SYNTH,
 203
 204                .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
 205        },
 206};
 207
 208static inline int output_type(unsigned int type)
 209{
 210        switch (type) {
 211        case PERF_TYPE_SYNTH:
 212                return OUTPUT_TYPE_SYNTH;
 213        default:
 214                return type;
 215        }
 216}
 217
 218static inline unsigned int attr_type(unsigned int type)
 219{
 220        switch (type) {
 221        case OUTPUT_TYPE_SYNTH:
 222                return PERF_TYPE_SYNTH;
 223        default:
 224                return type;
 225        }
 226}
 227
 228static bool output_set_by_user(void)
 229{
 230        int j;
 231        for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
 232                if (output[j].user_set)
 233                        return true;
 234        }
 235        return false;
 236}
 237
 238static const char *output_field2str(enum perf_output_field field)
 239{
 240        int i, imax = ARRAY_SIZE(all_output_options);
 241        const char *str = "";
 242
 243        for (i = 0; i < imax; ++i) {
 244                if (all_output_options[i].field == field) {
 245                        str = all_output_options[i].str;
 246                        break;
 247                }
 248        }
 249        return str;
 250}
 251
 252#define PRINT_FIELD(x)  (output[output_type(attr->type)].fields & PERF_OUTPUT_##x)
 253
 254static int perf_evsel__do_check_stype(struct perf_evsel *evsel,
 255                                      u64 sample_type, const char *sample_msg,
 256                                      enum perf_output_field field,
 257                                      bool allow_user_set)
 258{
 259        struct perf_event_attr *attr = &evsel->attr;
 260        int type = output_type(attr->type);
 261        const char *evname;
 262
 263        if (attr->sample_type & sample_type)
 264                return 0;
 265
 266        if (output[type].user_set) {
 267                if (allow_user_set)
 268                        return 0;
 269                evname = perf_evsel__name(evsel);
 270                pr_err("Samples for '%s' event do not have %s attribute set. "
 271                       "Cannot print '%s' field.\n",
 272                       evname, sample_msg, output_field2str(field));
 273                return -1;
 274        }
 275
 276        /* user did not ask for it explicitly so remove from the default list */
 277        output[type].fields &= ~field;
 278        evname = perf_evsel__name(evsel);
 279        pr_debug("Samples for '%s' event do not have %s attribute set. "
 280                 "Skipping '%s' field.\n",
 281                 evname, sample_msg, output_field2str(field));
 282
 283        return 0;
 284}
 285
 286static int perf_evsel__check_stype(struct perf_evsel *evsel,
 287                                   u64 sample_type, const char *sample_msg,
 288                                   enum perf_output_field field)
 289{
 290        return perf_evsel__do_check_stype(evsel, sample_type, sample_msg, field,
 291                                          false);
 292}
 293
 294static int perf_evsel__check_attr(struct perf_evsel *evsel,
 295                                  struct perf_session *session)
 296{
 297        struct perf_event_attr *attr = &evsel->attr;
 298        bool allow_user_set;
 299
 300        if (perf_header__has_feat(&session->header, HEADER_STAT))
 301                return 0;
 302
 303        allow_user_set = perf_header__has_feat(&session->header,
 304                                               HEADER_AUXTRACE);
 305
 306        if (PRINT_FIELD(TRACE) &&
 307                !perf_session__has_traces(session, "record -R"))
 308                return -EINVAL;
 309
 310        if (PRINT_FIELD(IP)) {
 311                if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP",
 312                                            PERF_OUTPUT_IP))
 313                        return -EINVAL;
 314        }
 315
 316        if (PRINT_FIELD(ADDR) &&
 317                perf_evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR",
 318                                           PERF_OUTPUT_ADDR, allow_user_set))
 319                return -EINVAL;
 320
 321        if (PRINT_FIELD(DATA_SRC) &&
 322                perf_evsel__check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC",
 323                                        PERF_OUTPUT_DATA_SRC))
 324                return -EINVAL;
 325
 326        if (PRINT_FIELD(WEIGHT) &&
 327                perf_evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT, "WEIGHT",
 328                                        PERF_OUTPUT_WEIGHT))
 329                return -EINVAL;
 330
 331        if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
 332                pr_err("Display of symbols requested but neither sample IP nor "
 333                           "sample address\nis selected. Hence, no addresses to convert "
 334                       "to symbols.\n");
 335                return -EINVAL;
 336        }
 337        if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
 338                pr_err("Display of offsets requested but symbol is not"
 339                       "selected.\n");
 340                return -EINVAL;
 341        }
 342        if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR) &&
 343            !PRINT_FIELD(BRSTACK) && !PRINT_FIELD(BRSTACKSYM) && !PRINT_FIELD(BRSTACKOFF)) {
 344                pr_err("Display of DSO requested but no address to convert.  Select\n"
 345                       "sample IP, sample address, brstack, brstacksym, or brstackoff.\n");
 346                return -EINVAL;
 347        }
 348        if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) {
 349                pr_err("Display of source line number requested but sample IP is not\n"
 350                       "selected. Hence, no address to lookup the source line number.\n");
 351                return -EINVAL;
 352        }
 353        if (PRINT_FIELD(BRSTACKINSN) &&
 354            !(perf_evlist__combined_branch_type(session->evlist) &
 355              PERF_SAMPLE_BRANCH_ANY)) {
 356                pr_err("Display of branch stack assembler requested, but non all-branch filter set\n"
 357                       "Hint: run 'perf record -b ...'\n");
 358                return -EINVAL;
 359        }
 360        if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
 361                perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID",
 362                                        PERF_OUTPUT_TID|PERF_OUTPUT_PID))
 363                return -EINVAL;
 364
 365        if (PRINT_FIELD(TIME) &&
 366                perf_evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME",
 367                                        PERF_OUTPUT_TIME))
 368                return -EINVAL;
 369
 370        if (PRINT_FIELD(CPU) &&
 371                perf_evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU",
 372                                           PERF_OUTPUT_CPU, allow_user_set))
 373                return -EINVAL;
 374
 375        if (PRINT_FIELD(PERIOD) &&
 376                perf_evsel__check_stype(evsel, PERF_SAMPLE_PERIOD, "PERIOD",
 377                                        PERF_OUTPUT_PERIOD))
 378                return -EINVAL;
 379
 380        if (PRINT_FIELD(IREGS) &&
 381                perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS",
 382                                        PERF_OUTPUT_IREGS))
 383                return -EINVAL;
 384
 385        return 0;
 386}
 387
 388static void set_print_ip_opts(struct perf_event_attr *attr)
 389{
 390        unsigned int type = output_type(attr->type);
 391
 392        output[type].print_ip_opts = 0;
 393        if (PRINT_FIELD(IP))
 394                output[type].print_ip_opts |= EVSEL__PRINT_IP;
 395
 396        if (PRINT_FIELD(SYM))
 397                output[type].print_ip_opts |= EVSEL__PRINT_SYM;
 398
 399        if (PRINT_FIELD(DSO))
 400                output[type].print_ip_opts |= EVSEL__PRINT_DSO;
 401
 402        if (PRINT_FIELD(SYMOFFSET))
 403                output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET;
 404
 405        if (PRINT_FIELD(SRCLINE))
 406                output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
 407}
 408
 409/*
 410 * verify all user requested events exist and the samples
 411 * have the expected data
 412 */
 413static int perf_session__check_output_opt(struct perf_session *session)
 414{
 415        unsigned int j;
 416        struct perf_evsel *evsel;
 417
 418        for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
 419                evsel = perf_session__find_first_evtype(session, attr_type(j));
 420
 421                /*
 422                 * even if fields is set to 0 (ie., show nothing) event must
 423                 * exist if user explicitly includes it on the command line
 424                 */
 425                if (!evsel && output[j].user_set && !output[j].wildcard_set &&
 426                    j != OUTPUT_TYPE_SYNTH) {
 427                        pr_err("%s events do not exist. "
 428                               "Remove corresponding -F option to proceed.\n",
 429                               event_type(j));
 430                        return -1;
 431                }
 432
 433                if (evsel && output[j].fields &&
 434                        perf_evsel__check_attr(evsel, session))
 435                        return -1;
 436
 437                if (evsel == NULL)
 438                        continue;
 439
 440                set_print_ip_opts(&evsel->attr);
 441        }
 442
 443        if (!no_callchain) {
 444                bool use_callchain = false;
 445                bool not_pipe = false;
 446
 447                evlist__for_each_entry(session->evlist, evsel) {
 448                        not_pipe = true;
 449                        if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
 450                                use_callchain = true;
 451                                break;
 452                        }
 453                }
 454                if (not_pipe && !use_callchain)
 455                        symbol_conf.use_callchain = false;
 456        }
 457
 458        /*
 459         * set default for tracepoints to print symbols only
 460         * if callchains are present
 461         */
 462        if (symbol_conf.use_callchain &&
 463            !output[PERF_TYPE_TRACEPOINT].user_set) {
 464                struct perf_event_attr *attr;
 465
 466                j = PERF_TYPE_TRACEPOINT;
 467
 468                evlist__for_each_entry(session->evlist, evsel) {
 469                        if (evsel->attr.type != j)
 470                                continue;
 471
 472                        attr = &evsel->attr;
 473
 474                        if (attr->sample_type & PERF_SAMPLE_CALLCHAIN) {
 475                                output[j].fields |= PERF_OUTPUT_IP;
 476                                output[j].fields |= PERF_OUTPUT_SYM;
 477                                output[j].fields |= PERF_OUTPUT_DSO;
 478                                set_print_ip_opts(attr);
 479                                goto out;
 480                        }
 481                }
 482        }
 483
 484out:
 485        return 0;
 486}
 487
 488static void print_sample_iregs(struct perf_sample *sample,
 489                          struct perf_event_attr *attr)
 490{
 491        struct regs_dump *regs = &sample->intr_regs;
 492        uint64_t mask = attr->sample_regs_intr;
 493        unsigned i = 0, r;
 494
 495        if (!regs)
 496                return;
 497
 498        for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
 499                u64 val = regs->regs[i++];
 500                printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
 501        }
 502}
 503
 504static void print_sample_start(struct perf_sample *sample,
 505                               struct thread *thread,
 506                               struct perf_evsel *evsel)
 507{
 508        struct perf_event_attr *attr = &evsel->attr;
 509        unsigned long secs;
 510        unsigned long long nsecs;
 511
 512        if (PRINT_FIELD(COMM)) {
 513                if (latency_format)
 514                        printf("%8.8s ", thread__comm_str(thread));
 515                else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
 516                        printf("%s ", thread__comm_str(thread));
 517                else
 518                        printf("%16s ", thread__comm_str(thread));
 519        }
 520
 521        if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
 522                printf("%5d/%-5d ", sample->pid, sample->tid);
 523        else if (PRINT_FIELD(PID))
 524                printf("%5d ", sample->pid);
 525        else if (PRINT_FIELD(TID))
 526                printf("%5d ", sample->tid);
 527
 528        if (PRINT_FIELD(CPU)) {
 529                if (latency_format)
 530                        printf("%3d ", sample->cpu);
 531                else
 532                        printf("[%03d] ", sample->cpu);
 533        }
 534
 535        if (PRINT_FIELD(TIME)) {
 536                nsecs = sample->time;
 537                secs = nsecs / NSEC_PER_SEC;
 538                nsecs -= secs * NSEC_PER_SEC;
 539
 540                if (nanosecs)
 541                        printf("%5lu.%09llu: ", secs, nsecs);
 542                else {
 543                        char sample_time[32];
 544                        timestamp__scnprintf_usec(sample->time, sample_time, sizeof(sample_time));
 545                        printf("%12s: ", sample_time);
 546                }
 547        }
 548}
 549
 550static inline char
 551mispred_str(struct branch_entry *br)
 552{
 553        if (!(br->flags.mispred  || br->flags.predicted))
 554                return '-';
 555
 556        return br->flags.predicted ? 'P' : 'M';
 557}
 558
 559static void print_sample_brstack(struct perf_sample *sample,
 560                                 struct thread *thread,
 561                                 struct perf_event_attr *attr)
 562{
 563        struct branch_stack *br = sample->branch_stack;
 564        struct addr_location alf, alt;
 565        u64 i, from, to;
 566
 567        if (!(br && br->nr))
 568                return;
 569
 570        for (i = 0; i < br->nr; i++) {
 571                from = br->entries[i].from;
 572                to   = br->entries[i].to;
 573
 574                if (PRINT_FIELD(DSO)) {
 575                        memset(&alf, 0, sizeof(alf));
 576                        memset(&alt, 0, sizeof(alt));
 577                        thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf);
 578                        thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
 579                }
 580
 581                printf("0x%"PRIx64, from);
 582                if (PRINT_FIELD(DSO)) {
 583                        printf("(");
 584                        map__fprintf_dsoname(alf.map, stdout);
 585                        printf(")");
 586                }
 587
 588                printf("/0x%"PRIx64, to);
 589                if (PRINT_FIELD(DSO)) {
 590                        printf("(");
 591                        map__fprintf_dsoname(alt.map, stdout);
 592                        printf(")");
 593                }
 594
 595                printf("/%c/%c/%c/%d ",
 596                        mispred_str( br->entries + i),
 597                        br->entries[i].flags.in_tx? 'X' : '-',
 598                        br->entries[i].flags.abort? 'A' : '-',
 599                        br->entries[i].flags.cycles);
 600        }
 601}
 602
 603static void print_sample_brstacksym(struct perf_sample *sample,
 604                                    struct thread *thread,
 605                                    struct perf_event_attr *attr)
 606{
 607        struct branch_stack *br = sample->branch_stack;
 608        struct addr_location alf, alt;
 609        u64 i, from, to;
 610
 611        if (!(br && br->nr))
 612                return;
 613
 614        for (i = 0; i < br->nr; i++) {
 615
 616                memset(&alf, 0, sizeof(alf));
 617                memset(&alt, 0, sizeof(alt));
 618                from = br->entries[i].from;
 619                to   = br->entries[i].to;
 620
 621                thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf);
 622                if (alf.map)
 623                        alf.sym = map__find_symbol(alf.map, alf.addr);
 624
 625                thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
 626                if (alt.map)
 627                        alt.sym = map__find_symbol(alt.map, alt.addr);
 628
 629                symbol__fprintf_symname_offs(alf.sym, &alf, stdout);
 630                if (PRINT_FIELD(DSO)) {
 631                        printf("(");
 632                        map__fprintf_dsoname(alf.map, stdout);
 633                        printf(")");
 634                }
 635                putchar('/');
 636                symbol__fprintf_symname_offs(alt.sym, &alt, stdout);
 637                if (PRINT_FIELD(DSO)) {
 638                        printf("(");
 639                        map__fprintf_dsoname(alt.map, stdout);
 640                        printf(")");
 641                }
 642                printf("/%c/%c/%c/%d ",
 643                        mispred_str( br->entries + i),
 644                        br->entries[i].flags.in_tx? 'X' : '-',
 645                        br->entries[i].flags.abort? 'A' : '-',
 646                        br->entries[i].flags.cycles);
 647        }
 648}
 649
 650static void print_sample_brstackoff(struct perf_sample *sample,
 651                                    struct thread *thread,
 652                                    struct perf_event_attr *attr)
 653{
 654        struct branch_stack *br = sample->branch_stack;
 655        struct addr_location alf, alt;
 656        u64 i, from, to;
 657
 658        if (!(br && br->nr))
 659                return;
 660
 661        for (i = 0; i < br->nr; i++) {
 662
 663                memset(&alf, 0, sizeof(alf));
 664                memset(&alt, 0, sizeof(alt));
 665                from = br->entries[i].from;
 666                to   = br->entries[i].to;
 667
 668                thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf);
 669                if (alf.map && !alf.map->dso->adjust_symbols)
 670                        from = map__map_ip(alf.map, from);
 671
 672                thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
 673                if (alt.map && !alt.map->dso->adjust_symbols)
 674                        to = map__map_ip(alt.map, to);
 675
 676                printf("0x%"PRIx64, from);
 677                if (PRINT_FIELD(DSO)) {
 678                        printf("(");
 679                        map__fprintf_dsoname(alf.map, stdout);
 680                        printf(")");
 681                }
 682                printf("/0x%"PRIx64, to);
 683                if (PRINT_FIELD(DSO)) {
 684                        printf("(");
 685                        map__fprintf_dsoname(alt.map, stdout);
 686                        printf(")");
 687                }
 688                printf("/%c/%c/%c/%d ",
 689                        mispred_str(br->entries + i),
 690                        br->entries[i].flags.in_tx ? 'X' : '-',
 691                        br->entries[i].flags.abort ? 'A' : '-',
 692                        br->entries[i].flags.cycles);
 693        }
 694}
 695#define MAXBB 16384UL
 696
 697static int grab_bb(u8 *buffer, u64 start, u64 end,
 698                    struct machine *machine, struct thread *thread,
 699                    bool *is64bit, u8 *cpumode, bool last)
 700{
 701        long offset, len;
 702        struct addr_location al;
 703        bool kernel;
 704
 705        if (!start || !end)
 706                return 0;
 707
 708        kernel = machine__kernel_ip(machine, start);
 709        if (kernel)
 710                *cpumode = PERF_RECORD_MISC_KERNEL;
 711        else
 712                *cpumode = PERF_RECORD_MISC_USER;
 713
 714        /*
 715         * Block overlaps between kernel and user.
 716         * This can happen due to ring filtering
 717         * On Intel CPUs the entry into the kernel is filtered,
 718         * but the exit is not. Let the caller patch it up.
 719         */
 720        if (kernel != machine__kernel_ip(machine, end)) {
 721                printf("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n",
 722                                start, end);
 723                return -ENXIO;
 724        }
 725
 726        memset(&al, 0, sizeof(al));
 727        if (end - start > MAXBB - MAXINSN) {
 728                if (last)
 729                        printf("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end);
 730                else
 731                        printf("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start);
 732                return 0;
 733        }
 734
 735        thread__find_addr_map(thread, *cpumode, MAP__FUNCTION, start, &al);
 736        if (!al.map || !al.map->dso) {
 737                printf("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
 738                return 0;
 739        }
 740        if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) {
 741                printf("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
 742                return 0;
 743        }
 744
 745        /* Load maps to ensure dso->is_64_bit has been updated */
 746        map__load(al.map);
 747
 748        offset = al.map->map_ip(al.map, start);
 749        len = dso__data_read_offset(al.map->dso, machine, offset, (u8 *)buffer,
 750                                    end - start + MAXINSN);
 751
 752        *is64bit = al.map->dso->is_64_bit;
 753        if (len <= 0)
 754                printf("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
 755                        start, end);
 756        return len;
 757}
 758
 759static void print_jump(uint64_t ip, struct branch_entry *en,
 760                       struct perf_insn *x, u8 *inbuf, int len,
 761                       int insn)
 762{
 763        printf("\t%016" PRIx64 "\t%-30s\t#%s%s%s%s",
 764               ip,
 765               dump_insn(x, ip, inbuf, len, NULL),
 766               en->flags.predicted ? " PRED" : "",
 767               en->flags.mispred ? " MISPRED" : "",
 768               en->flags.in_tx ? " INTX" : "",
 769               en->flags.abort ? " ABORT" : "");
 770        if (en->flags.cycles) {
 771                printf(" %d cycles", en->flags.cycles);
 772                if (insn)
 773                        printf(" %.2f IPC", (float)insn / en->flags.cycles);
 774        }
 775        putchar('\n');
 776}
 777
 778static void print_ip_sym(struct thread *thread, u8 cpumode, int cpu,
 779                         uint64_t addr, struct symbol **lastsym,
 780                         struct perf_event_attr *attr)
 781{
 782        struct addr_location al;
 783        int off;
 784
 785        memset(&al, 0, sizeof(al));
 786
 787        thread__find_addr_map(thread, cpumode, MAP__FUNCTION, addr, &al);
 788        if (!al.map)
 789                thread__find_addr_map(thread, cpumode, MAP__VARIABLE,
 790                                      addr, &al);
 791        if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
 792                return;
 793
 794        al.cpu = cpu;
 795        al.sym = NULL;
 796        if (al.map)
 797                al.sym = map__find_symbol(al.map, al.addr);
 798
 799        if (!al.sym)
 800                return;
 801
 802        if (al.addr < al.sym->end)
 803                off = al.addr - al.sym->start;
 804        else
 805                off = al.addr - al.map->start - al.sym->start;
 806        printf("\t%s", al.sym->name);
 807        if (off)
 808                printf("%+d", off);
 809        putchar(':');
 810        if (PRINT_FIELD(SRCLINE))
 811                map__fprintf_srcline(al.map, al.addr, "\t", stdout);
 812        putchar('\n');
 813        *lastsym = al.sym;
 814}
 815
 816static void print_sample_brstackinsn(struct perf_sample *sample,
 817                                     struct thread *thread,
 818                                     struct perf_event_attr *attr,
 819                                     struct machine *machine)
 820{
 821        struct branch_stack *br = sample->branch_stack;
 822        u64 start, end;
 823        int i, insn, len, nr, ilen;
 824        struct perf_insn x;
 825        u8 buffer[MAXBB];
 826        unsigned off;
 827        struct symbol *lastsym = NULL;
 828
 829        if (!(br && br->nr))
 830                return;
 831        nr = br->nr;
 832        if (max_blocks && nr > max_blocks + 1)
 833                nr = max_blocks + 1;
 834
 835        x.thread = thread;
 836        x.cpu = sample->cpu;
 837
 838        putchar('\n');
 839
 840        /* Handle first from jump, of which we don't know the entry. */
 841        len = grab_bb(buffer, br->entries[nr-1].from,
 842                        br->entries[nr-1].from,
 843                        machine, thread, &x.is64bit, &x.cpumode, false);
 844        if (len > 0) {
 845                print_ip_sym(thread, x.cpumode, x.cpu,
 846                             br->entries[nr - 1].from, &lastsym, attr);
 847                print_jump(br->entries[nr - 1].from, &br->entries[nr - 1],
 848                            &x, buffer, len, 0);
 849        }
 850
 851        /* Print all blocks */
 852        for (i = nr - 2; i >= 0; i--) {
 853                if (br->entries[i].from || br->entries[i].to)
 854                        pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i,
 855                                 br->entries[i].from,
 856                                 br->entries[i].to);
 857                start = br->entries[i + 1].to;
 858                end   = br->entries[i].from;
 859
 860                len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
 861                /* Patch up missing kernel transfers due to ring filters */
 862                if (len == -ENXIO && i > 0) {
 863                        end = br->entries[--i].from;
 864                        pr_debug("\tpatching up to %" PRIx64 "-%" PRIx64 "\n", start, end);
 865                        len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
 866                }
 867                if (len <= 0)
 868                        continue;
 869
 870                insn = 0;
 871                for (off = 0;; off += ilen) {
 872                        uint64_t ip = start + off;
 873
 874                        print_ip_sym(thread, x.cpumode, x.cpu, ip, &lastsym, attr);
 875                        if (ip == end) {
 876                                print_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn);
 877                                break;
 878                        } else {
 879                                printf("\t%016" PRIx64 "\t%s\n", ip,
 880                                        dump_insn(&x, ip, buffer + off, len - off, &ilen));
 881                                if (ilen == 0)
 882                                        break;
 883                                insn++;
 884                        }
 885                }
 886        }
 887
 888        /*
 889         * Hit the branch? In this case we are already done, and the target
 890         * has not been executed yet.
 891         */
 892        if (br->entries[0].from == sample->ip)
 893                return;
 894        if (br->entries[0].flags.abort)
 895                return;
 896
 897        /*
 898         * Print final block upto sample
 899         */
 900        start = br->entries[0].to;
 901        end = sample->ip;
 902        len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
 903        print_ip_sym(thread, x.cpumode, x.cpu, start, &lastsym, attr);
 904        if (len <= 0) {
 905                /* Print at least last IP if basic block did not work */
 906                len = grab_bb(buffer, sample->ip, sample->ip,
 907                              machine, thread, &x.is64bit, &x.cpumode, false);
 908                if (len <= 0)
 909                        return;
 910
 911                printf("\t%016" PRIx64 "\t%s\n", sample->ip,
 912                        dump_insn(&x, sample->ip, buffer, len, NULL));
 913                return;
 914        }
 915        for (off = 0; off <= end - start; off += ilen) {
 916                printf("\t%016" PRIx64 "\t%s\n", start + off,
 917                        dump_insn(&x, start + off, buffer + off, len - off, &ilen));
 918                if (ilen == 0)
 919                        break;
 920        }
 921}
 922
 923static void print_sample_addr(struct perf_sample *sample,
 924                          struct thread *thread,
 925                          struct perf_event_attr *attr)
 926{
 927        struct addr_location al;
 928
 929        printf("%16" PRIx64, sample->addr);
 930
 931        if (!sample_addr_correlates_sym(attr))
 932                return;
 933
 934        thread__resolve(thread, &al, sample);
 935
 936        if (PRINT_FIELD(SYM)) {
 937                printf(" ");
 938                if (PRINT_FIELD(SYMOFFSET))
 939                        symbol__fprintf_symname_offs(al.sym, &al, stdout);
 940                else
 941                        symbol__fprintf_symname(al.sym, stdout);
 942        }
 943
 944        if (PRINT_FIELD(DSO)) {
 945                printf(" (");
 946                map__fprintf_dsoname(al.map, stdout);
 947                printf(")");
 948        }
 949}
 950
 951static void print_sample_callindent(struct perf_sample *sample,
 952                                    struct perf_evsel *evsel,
 953                                    struct thread *thread,
 954                                    struct addr_location *al)
 955{
 956        struct perf_event_attr *attr = &evsel->attr;
 957        size_t depth = thread_stack__depth(thread);
 958        struct addr_location addr_al;
 959        const char *name = NULL;
 960        static int spacing;
 961        int len = 0;
 962        u64 ip = 0;
 963
 964        /*
 965         * The 'return' has already been popped off the stack so the depth has
 966         * to be adjusted to match the 'call'.
 967         */
 968        if (thread->ts && sample->flags & PERF_IP_FLAG_RETURN)
 969                depth += 1;
 970
 971        if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) {
 972                if (sample_addr_correlates_sym(attr)) {
 973                        thread__resolve(thread, &addr_al, sample);
 974                        if (addr_al.sym)
 975                                name = addr_al.sym->name;
 976                        else
 977                                ip = sample->addr;
 978                } else {
 979                        ip = sample->addr;
 980                }
 981        } else if (sample->flags & (PERF_IP_FLAG_RETURN | PERF_IP_FLAG_TRACE_END)) {
 982                if (al->sym)
 983                        name = al->sym->name;
 984                else
 985                        ip = sample->ip;
 986        }
 987
 988        if (name)
 989                len = printf("%*s%s", (int)depth * 4, "", name);
 990        else if (ip)
 991                len = printf("%*s%16" PRIx64, (int)depth * 4, "", ip);
 992
 993        if (len < 0)
 994                return;
 995
 996        /*
 997         * Try to keep the output length from changing frequently so that the
 998         * output lines up more nicely.
 999         */
1000        if (len > spacing || (len && len < spacing - 52))
1001                spacing = round_up(len + 4, 32);
1002
1003        if (len < spacing)
1004                printf("%*s", spacing - len, "");
1005}
1006
1007static void print_insn(struct perf_sample *sample,
1008                       struct perf_event_attr *attr,
1009                       struct thread *thread,
1010                       struct machine *machine)
1011{
1012        if (PRINT_FIELD(INSNLEN))
1013                printf(" ilen: %d", sample->insn_len);
1014        if (PRINT_FIELD(INSN)) {
1015                int i;
1016
1017                printf(" insn:");
1018                for (i = 0; i < sample->insn_len; i++)
1019                        printf(" %02x", (unsigned char)sample->insn[i]);
1020        }
1021        if (PRINT_FIELD(BRSTACKINSN))
1022                print_sample_brstackinsn(sample, thread, attr, machine);
1023}
1024
1025static void print_sample_bts(struct perf_sample *sample,
1026                             struct perf_evsel *evsel,
1027                             struct thread *thread,
1028                             struct addr_location *al,
1029                             struct machine *machine)
1030{
1031        struct perf_event_attr *attr = &evsel->attr;
1032        unsigned int type = output_type(attr->type);
1033        bool print_srcline_last = false;
1034
1035        if (PRINT_FIELD(CALLINDENT))
1036                print_sample_callindent(sample, evsel, thread, al);
1037
1038        /* print branch_from information */
1039        if (PRINT_FIELD(IP)) {
1040                unsigned int print_opts = output[type].print_ip_opts;
1041                struct callchain_cursor *cursor = NULL;
1042
1043                if (symbol_conf.use_callchain && sample->callchain &&
1044                    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
1045                                              sample, NULL, NULL, scripting_max_stack) == 0)
1046                        cursor = &callchain_cursor;
1047
1048                if (cursor == NULL) {
1049                        putchar(' ');
1050                        if (print_opts & EVSEL__PRINT_SRCLINE) {
1051                                print_srcline_last = true;
1052                                print_opts &= ~EVSEL__PRINT_SRCLINE;
1053                        }
1054                } else
1055                        putchar('\n');
1056
1057                sample__fprintf_sym(sample, al, 0, print_opts, cursor, stdout);
1058        }
1059
1060        /* print branch_to information */
1061        if (PRINT_FIELD(ADDR) ||
1062            ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
1063             !output[type].user_set)) {
1064                printf(" => ");
1065                print_sample_addr(sample, thread, attr);
1066        }
1067
1068        if (print_srcline_last)
1069                map__fprintf_srcline(al->map, al->addr, "\n  ", stdout);
1070
1071        print_insn(sample, attr, thread, machine);
1072
1073        printf("\n");
1074}
1075
1076static struct {
1077        u32 flags;
1078        const char *name;
1079} sample_flags[] = {
1080        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},
1081        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},
1082        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"},
1083        {PERF_IP_FLAG_BRANCH, "jmp"},
1084        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"},
1085        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"},
1086        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"},
1087        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"},
1088        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"},
1089        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT, "hw int"},
1090        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"},
1091        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"},
1092        {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"},
1093        {0, NULL}
1094};
1095
1096static void print_sample_flags(u32 flags)
1097{
1098        const char *chars = PERF_IP_FLAG_CHARS;
1099        const int n = strlen(PERF_IP_FLAG_CHARS);
1100        bool in_tx = flags & PERF_IP_FLAG_IN_TX;
1101        const char *name = NULL;
1102        char str[33];
1103        int i, pos = 0;
1104
1105        for (i = 0; sample_flags[i].name ; i++) {
1106                if (sample_flags[i].flags == (flags & ~PERF_IP_FLAG_IN_TX)) {
1107                        name = sample_flags[i].name;
1108                        break;
1109                }
1110        }
1111
1112        for (i = 0; i < n; i++, flags >>= 1) {
1113                if (flags & 1)
1114                        str[pos++] = chars[i];
1115        }
1116        for (; i < 32; i++, flags >>= 1) {
1117                if (flags & 1)
1118                        str[pos++] = '?';
1119        }
1120        str[pos] = 0;
1121
1122        if (name)
1123                printf("  %-7s%4s ", name, in_tx ? "(x)" : "");
1124        else
1125                printf("  %-11s ", str);
1126}
1127
1128struct printer_data {
1129        int line_no;
1130        bool hit_nul;
1131        bool is_printable;
1132};
1133
1134static void
1135print_sample_bpf_output_printer(enum binary_printer_ops op,
1136                                unsigned int val,
1137                                void *extra)
1138{
1139        unsigned char ch = (unsigned char)val;
1140        struct printer_data *printer_data = extra;
1141
1142        switch (op) {
1143        case BINARY_PRINT_DATA_BEGIN:
1144                printf("\n");
1145                break;
1146        case BINARY_PRINT_LINE_BEGIN:
1147                printf("%17s", !printer_data->line_no ? "BPF output:" :
1148                                                        "           ");
1149                break;
1150        case BINARY_PRINT_ADDR:
1151                printf(" %04x:", val);
1152                break;
1153        case BINARY_PRINT_NUM_DATA:
1154                printf(" %02x", val);
1155                break;
1156        case BINARY_PRINT_NUM_PAD:
1157                printf("   ");
1158                break;
1159        case BINARY_PRINT_SEP:
1160                printf("  ");
1161                break;
1162        case BINARY_PRINT_CHAR_DATA:
1163                if (printer_data->hit_nul && ch)
1164                        printer_data->is_printable = false;
1165
1166                if (!isprint(ch)) {
1167                        printf("%c", '.');
1168
1169                        if (!printer_data->is_printable)
1170                                break;
1171
1172                        if (ch == '\0')
1173                                printer_data->hit_nul = true;
1174                        else
1175                                printer_data->is_printable = false;
1176                } else {
1177                        printf("%c", ch);
1178                }
1179                break;
1180        case BINARY_PRINT_CHAR_PAD:
1181                printf(" ");
1182                break;
1183        case BINARY_PRINT_LINE_END:
1184                printf("\n");
1185                printer_data->line_no++;
1186                break;
1187        case BINARY_PRINT_DATA_END:
1188        default:
1189                break;
1190        }
1191}
1192
1193static void print_sample_bpf_output(struct perf_sample *sample)
1194{
1195        unsigned int nr_bytes = sample->raw_size;
1196        struct printer_data printer_data = {0, false, true};
1197
1198        print_binary(sample->raw_data, nr_bytes, 8,
1199                     print_sample_bpf_output_printer, &printer_data);
1200
1201        if (printer_data.is_printable && printer_data.hit_nul)
1202                printf("%17s \"%s\"\n", "BPF string:",
1203                       (char *)(sample->raw_data));
1204}
1205
1206static void print_sample_spacing(int len, int spacing)
1207{
1208        if (len > 0 && len < spacing)
1209                printf("%*s", spacing - len, "");
1210}
1211
1212static void print_sample_pt_spacing(int len)
1213{
1214        print_sample_spacing(len, 34);
1215}
1216
1217static void print_sample_synth_ptwrite(struct perf_sample *sample)
1218{
1219        struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
1220        int len;
1221
1222        if (perf_sample__bad_synth_size(sample, *data))
1223                return;
1224
1225        len = printf(" IP: %u payload: %#" PRIx64 " ",
1226                     data->ip, le64_to_cpu(data->payload));
1227        print_sample_pt_spacing(len);
1228}
1229
1230static void print_sample_synth_mwait(struct perf_sample *sample)
1231{
1232        struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
1233        int len;
1234
1235        if (perf_sample__bad_synth_size(sample, *data))
1236                return;
1237
1238        len = printf(" hints: %#x extensions: %#x ",
1239                     data->hints, data->extensions);
1240        print_sample_pt_spacing(len);
1241}
1242
1243static void print_sample_synth_pwre(struct perf_sample *sample)
1244{
1245        struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
1246        int len;
1247
1248        if (perf_sample__bad_synth_size(sample, *data))
1249                return;
1250
1251        len = printf(" hw: %u cstate: %u sub-cstate: %u ",
1252                     data->hw, data->cstate, data->subcstate);
1253        print_sample_pt_spacing(len);
1254}
1255
1256static void print_sample_synth_exstop(struct perf_sample *sample)
1257{
1258        struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
1259        int len;
1260
1261        if (perf_sample__bad_synth_size(sample, *data))
1262                return;
1263
1264        len = printf(" IP: %u ", data->ip);
1265        print_sample_pt_spacing(len);
1266}
1267
1268static void print_sample_synth_pwrx(struct perf_sample *sample)
1269{
1270        struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
1271        int len;
1272
1273        if (perf_sample__bad_synth_size(sample, *data))
1274                return;
1275
1276        len = printf(" deepest cstate: %u last cstate: %u wake reason: %#x ",
1277                     data->deepest_cstate, data->last_cstate,
1278                     data->wake_reason);
1279        print_sample_pt_spacing(len);
1280}
1281
1282static void print_sample_synth_cbr(struct perf_sample *sample)
1283{
1284        struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample);
1285        unsigned int percent, freq;
1286        int len;
1287
1288        if (perf_sample__bad_synth_size(sample, *data))
1289                return;
1290
1291        freq = (le32_to_cpu(data->freq) + 500) / 1000;
1292        len = printf(" cbr: %2u freq: %4u MHz ", data->cbr, freq);
1293        if (data->max_nonturbo) {
1294                percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
1295                len += printf("(%3u%%) ", percent);
1296        }
1297        print_sample_pt_spacing(len);
1298}
1299
1300static void print_sample_synth(struct perf_sample *sample,
1301                               struct perf_evsel *evsel)
1302{
1303        switch (evsel->attr.config) {
1304        case PERF_SYNTH_INTEL_PTWRITE:
1305                print_sample_synth_ptwrite(sample);
1306                break;
1307        case PERF_SYNTH_INTEL_MWAIT:
1308                print_sample_synth_mwait(sample);
1309                break;
1310        case PERF_SYNTH_INTEL_PWRE:
1311                print_sample_synth_pwre(sample);
1312                break;
1313        case PERF_SYNTH_INTEL_EXSTOP:
1314                print_sample_synth_exstop(sample);
1315                break;
1316        case PERF_SYNTH_INTEL_PWRX:
1317                print_sample_synth_pwrx(sample);
1318                break;
1319        case PERF_SYNTH_INTEL_CBR:
1320                print_sample_synth_cbr(sample);
1321                break;
1322        default:
1323                break;
1324        }
1325}
1326
1327struct perf_script {
1328        struct perf_tool        tool;
1329        struct perf_session     *session;
1330        bool                    show_task_events;
1331        bool                    show_mmap_events;
1332        bool                    show_switch_events;
1333        bool                    show_namespace_events;
1334        bool                    allocated;
1335        struct cpu_map          *cpus;
1336        struct thread_map       *threads;
1337        int                     name_width;
1338        const char              *time_str;
1339        struct perf_time_interval ptime;
1340};
1341
1342static int perf_evlist__max_name_len(struct perf_evlist *evlist)
1343{
1344        struct perf_evsel *evsel;
1345        int max = 0;
1346
1347        evlist__for_each_entry(evlist, evsel) {
1348                int len = strlen(perf_evsel__name(evsel));
1349
1350                max = MAX(len, max);
1351        }
1352
1353        return max;
1354}
1355
1356static size_t data_src__printf(u64 data_src)
1357{
1358        struct mem_info mi = { .data_src.val = data_src };
1359        char decode[100];
1360        char out[100];
1361        static int maxlen;
1362        int len;
1363
1364        perf_script__meminfo_scnprintf(decode, 100, &mi);
1365
1366        len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode);
1367        if (maxlen < len)
1368                maxlen = len;
1369
1370        return printf("%-*s", maxlen, out);
1371}
1372
1373static void process_event(struct perf_script *script,
1374                          struct perf_sample *sample, struct perf_evsel *evsel,
1375                          struct addr_location *al,
1376                          struct machine *machine)
1377{
1378        struct thread *thread = al->thread;
1379        struct perf_event_attr *attr = &evsel->attr;
1380        unsigned int type = output_type(attr->type);
1381
1382        if (output[type].fields == 0)
1383                return;
1384
1385        print_sample_start(sample, thread, evsel);
1386
1387        if (PRINT_FIELD(PERIOD))
1388                printf("%10" PRIu64 " ", sample->period);
1389
1390        if (PRINT_FIELD(EVNAME)) {
1391                const char *evname = perf_evsel__name(evsel);
1392
1393                if (!script->name_width)
1394                        script->name_width = perf_evlist__max_name_len(script->session->evlist);
1395
1396                printf("%*s: ", script->name_width,
1397                       evname ? evname : "[unknown]");
1398        }
1399
1400        if (print_flags)
1401                print_sample_flags(sample->flags);
1402
1403        if (is_bts_event(attr)) {
1404                print_sample_bts(sample, evsel, thread, al, machine);
1405                return;
1406        }
1407
1408        if (PRINT_FIELD(TRACE))
1409                event_format__print(evsel->tp_format, sample->cpu,
1410                                    sample->raw_data, sample->raw_size);
1411
1412        if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
1413                print_sample_synth(sample, evsel);
1414
1415        if (PRINT_FIELD(ADDR))
1416                print_sample_addr(sample, thread, attr);
1417
1418        if (PRINT_FIELD(DATA_SRC))
1419                data_src__printf(sample->data_src);
1420
1421        if (PRINT_FIELD(WEIGHT))
1422                printf("%16" PRIu64, sample->weight);
1423
1424        if (PRINT_FIELD(IP)) {
1425                struct callchain_cursor *cursor = NULL;
1426
1427                if (symbol_conf.use_callchain && sample->callchain &&
1428                    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
1429                                              sample, NULL, NULL, scripting_max_stack) == 0)
1430                        cursor = &callchain_cursor;
1431
1432                putchar(cursor ? '\n' : ' ');
1433                sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, stdout);
1434        }
1435
1436        if (PRINT_FIELD(IREGS))
1437                print_sample_iregs(sample, attr);
1438
1439        if (PRINT_FIELD(BRSTACK))
1440                print_sample_brstack(sample, thread, attr);
1441        else if (PRINT_FIELD(BRSTACKSYM))
1442                print_sample_brstacksym(sample, thread, attr);
1443        else if (PRINT_FIELD(BRSTACKOFF))
1444                print_sample_brstackoff(sample, thread, attr);
1445
1446        if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
1447                print_sample_bpf_output(sample);
1448        print_insn(sample, attr, thread, machine);
1449        printf("\n");
1450}
1451
1452static struct scripting_ops     *scripting_ops;
1453
1454static void __process_stat(struct perf_evsel *counter, u64 tstamp)
1455{
1456        int nthreads = thread_map__nr(counter->threads);
1457        int ncpus = perf_evsel__nr_cpus(counter);
1458        int cpu, thread;
1459        static int header_printed;
1460
1461        if (counter->system_wide)
1462                nthreads = 1;
1463
1464        if (!header_printed) {
1465                printf("%3s %8s %15s %15s %15s %15s %s\n",
1466                       "CPU", "THREAD", "VAL", "ENA", "RUN", "TIME", "EVENT");
1467                header_printed = 1;
1468        }
1469
1470        for (thread = 0; thread < nthreads; thread++) {
1471                for (cpu = 0; cpu < ncpus; cpu++) {
1472                        struct perf_counts_values *counts;
1473
1474                        counts = perf_counts(counter->counts, cpu, thread);
1475
1476                        printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n",
1477                                counter->cpus->map[cpu],
1478                                thread_map__pid(counter->threads, thread),
1479                                counts->val,
1480                                counts->ena,
1481                                counts->run,
1482                                tstamp,
1483                                perf_evsel__name(counter));
1484                }
1485        }
1486}
1487
1488static void process_stat(struct perf_evsel *counter, u64 tstamp)
1489{
1490        if (scripting_ops && scripting_ops->process_stat)
1491                scripting_ops->process_stat(&stat_config, counter, tstamp);
1492        else
1493                __process_stat(counter, tstamp);
1494}
1495
1496static void process_stat_interval(u64 tstamp)
1497{
1498        if (scripting_ops && scripting_ops->process_stat_interval)
1499                scripting_ops->process_stat_interval(tstamp);
1500}
1501
1502static void setup_scripting(void)
1503{
1504        setup_perl_scripting();
1505        setup_python_scripting();
1506}
1507
1508static int flush_scripting(void)
1509{
1510        return scripting_ops ? scripting_ops->flush_script() : 0;
1511}
1512
1513static int cleanup_scripting(void)
1514{
1515        pr_debug("\nperf script stopped\n");
1516
1517        return scripting_ops ? scripting_ops->stop_script() : 0;
1518}
1519
1520static int process_sample_event(struct perf_tool *tool,
1521                                union perf_event *event,
1522                                struct perf_sample *sample,
1523                                struct perf_evsel *evsel,
1524                                struct machine *machine)
1525{
1526        struct perf_script *scr = container_of(tool, struct perf_script, tool);
1527        struct addr_location al;
1528
1529        if (perf_time__skip_sample(&scr->ptime, sample->time))
1530                return 0;
1531
1532        if (debug_mode) {
1533                if (sample->time < last_timestamp) {
1534                        pr_err("Samples misordered, previous: %" PRIu64
1535                                " this: %" PRIu64 "\n", last_timestamp,
1536                                sample->time);
1537                        nr_unordered++;
1538                }
1539                last_timestamp = sample->time;
1540                return 0;
1541        }
1542
1543        if (machine__resolve(machine, &al, sample) < 0) {
1544                pr_err("problem processing %d event, skipping it.\n",
1545                       event->header.type);
1546                return -1;
1547        }
1548
1549        if (al.filtered)
1550                goto out_put;
1551
1552        if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
1553                goto out_put;
1554
1555        if (scripting_ops)
1556                scripting_ops->process_event(event, sample, evsel, &al);
1557        else
1558                process_event(scr, sample, evsel, &al, machine);
1559
1560out_put:
1561        addr_location__put(&al);
1562        return 0;
1563}
1564
1565static int process_attr(struct perf_tool *tool, union perf_event *event,
1566                        struct perf_evlist **pevlist)
1567{
1568        struct perf_script *scr = container_of(tool, struct perf_script, tool);
1569        struct perf_evlist *evlist;
1570        struct perf_evsel *evsel, *pos;
1571        int err;
1572
1573        err = perf_event__process_attr(tool, event, pevlist);
1574        if (err)
1575                return err;
1576
1577        evlist = *pevlist;
1578        evsel = perf_evlist__last(*pevlist);
1579
1580        if (evsel->attr.type >= PERF_TYPE_MAX &&
1581            evsel->attr.type != PERF_TYPE_SYNTH)
1582                return 0;
1583
1584        evlist__for_each_entry(evlist, pos) {
1585                if (pos->attr.type == evsel->attr.type && pos != evsel)
1586                        return 0;
1587        }
1588
1589        set_print_ip_opts(&evsel->attr);
1590
1591        if (evsel->attr.sample_type)
1592                err = perf_evsel__check_attr(evsel, scr->session);
1593
1594        return err;
1595}
1596
1597static int process_comm_event(struct perf_tool *tool,
1598                              union perf_event *event,
1599                              struct perf_sample *sample,
1600                              struct machine *machine)
1601{
1602        struct thread *thread;
1603        struct perf_script *script = container_of(tool, struct perf_script, tool);
1604        struct perf_session *session = script->session;
1605        struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1606        int ret = -1;
1607
1608        thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid);
1609        if (thread == NULL) {
1610                pr_debug("problem processing COMM event, skipping it.\n");
1611                return -1;
1612        }
1613
1614        if (perf_event__process_comm(tool, event, sample, machine) < 0)
1615                goto out;
1616
1617        if (!evsel->attr.sample_id_all) {
1618                sample->cpu = 0;
1619                sample->time = 0;
1620                sample->tid = event->comm.tid;
1621                sample->pid = event->comm.pid;
1622        }
1623        print_sample_start(sample, thread, evsel);
1624        perf_event__fprintf(event, stdout);
1625        ret = 0;
1626out:
1627        thread__put(thread);
1628        return ret;
1629}
1630
1631static int process_namespaces_event(struct perf_tool *tool,
1632                                    union perf_event *event,
1633                                    struct perf_sample *sample,
1634                                    struct machine *machine)
1635{
1636        struct thread *thread;
1637        struct perf_script *script = container_of(tool, struct perf_script, tool);
1638        struct perf_session *session = script->session;
1639        struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1640        int ret = -1;
1641
1642        thread = machine__findnew_thread(machine, event->namespaces.pid,
1643                                         event->namespaces.tid);
1644        if (thread == NULL) {
1645                pr_debug("problem processing NAMESPACES event, skipping it.\n");
1646                return -1;
1647        }
1648
1649        if (perf_event__process_namespaces(tool, event, sample, machine) < 0)
1650                goto out;
1651
1652        if (!evsel->attr.sample_id_all) {
1653                sample->cpu = 0;
1654                sample->time = 0;
1655                sample->tid = event->namespaces.tid;
1656                sample->pid = event->namespaces.pid;
1657        }
1658        print_sample_start(sample, thread, evsel);
1659        perf_event__fprintf(event, stdout);
1660        ret = 0;
1661out:
1662        thread__put(thread);
1663        return ret;
1664}
1665
1666static int process_fork_event(struct perf_tool *tool,
1667                              union perf_event *event,
1668                              struct perf_sample *sample,
1669                              struct machine *machine)
1670{
1671        struct thread *thread;
1672        struct perf_script *script = container_of(tool, struct perf_script, tool);
1673        struct perf_session *session = script->session;
1674        struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1675
1676        if (perf_event__process_fork(tool, event, sample, machine) < 0)
1677                return -1;
1678
1679        thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid);
1680        if (thread == NULL) {
1681                pr_debug("problem processing FORK event, skipping it.\n");
1682                return -1;
1683        }
1684
1685        if (!evsel->attr.sample_id_all) {
1686                sample->cpu = 0;
1687                sample->time = event->fork.time;
1688                sample->tid = event->fork.tid;
1689                sample->pid = event->fork.pid;
1690        }
1691        print_sample_start(sample, thread, evsel);
1692        perf_event__fprintf(event, stdout);
1693        thread__put(thread);
1694
1695        return 0;
1696}
1697static int process_exit_event(struct perf_tool *tool,
1698                              union perf_event *event,
1699                              struct perf_sample *sample,
1700                              struct machine *machine)
1701{
1702        int err = 0;
1703        struct thread *thread;
1704        struct perf_script *script = container_of(tool, struct perf_script, tool);
1705        struct perf_session *session = script->session;
1706        struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1707
1708        thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid);
1709        if (thread == NULL) {
1710                pr_debug("problem processing EXIT event, skipping it.\n");
1711                return -1;
1712        }
1713
1714        if (!evsel->attr.sample_id_all) {
1715                sample->cpu = 0;
1716                sample->time = 0;
1717                sample->tid = event->fork.tid;
1718                sample->pid = event->fork.pid;
1719        }
1720        print_sample_start(sample, thread, evsel);
1721        perf_event__fprintf(event, stdout);
1722
1723        if (perf_event__process_exit(tool, event, sample, machine) < 0)
1724                err = -1;
1725
1726        thread__put(thread);
1727        return err;
1728}
1729
1730static int process_mmap_event(struct perf_tool *tool,
1731                              union perf_event *event,
1732                              struct perf_sample *sample,
1733                              struct machine *machine)
1734{
1735        struct thread *thread;
1736        struct perf_script *script = container_of(tool, struct perf_script, tool);
1737        struct perf_session *session = script->session;
1738        struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1739
1740        if (perf_event__process_mmap(tool, event, sample, machine) < 0)
1741                return -1;
1742
1743        thread = machine__findnew_thread(machine, event->mmap.pid, event->mmap.tid);
1744        if (thread == NULL) {
1745                pr_debug("problem processing MMAP event, skipping it.\n");
1746                return -1;
1747        }
1748
1749        if (!evsel->attr.sample_id_all) {
1750                sample->cpu = 0;
1751                sample->time = 0;
1752                sample->tid = event->mmap.tid;
1753                sample->pid = event->mmap.pid;
1754        }
1755        print_sample_start(sample, thread, evsel);
1756        perf_event__fprintf(event, stdout);
1757        thread__put(thread);
1758        return 0;
1759}
1760
1761static int process_mmap2_event(struct perf_tool *tool,
1762                              union perf_event *event,
1763                              struct perf_sample *sample,
1764                              struct machine *machine)
1765{
1766        struct thread *thread;
1767        struct perf_script *script = container_of(tool, struct perf_script, tool);
1768        struct perf_session *session = script->session;
1769        struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1770
1771        if (perf_event__process_mmap2(tool, event, sample, machine) < 0)
1772                return -1;
1773
1774        thread = machine__findnew_thread(machine, event->mmap2.pid, event->mmap2.tid);
1775        if (thread == NULL) {
1776                pr_debug("problem processing MMAP2 event, skipping it.\n");
1777                return -1;
1778        }
1779
1780        if (!evsel->attr.sample_id_all) {
1781                sample->cpu = 0;
1782                sample->time = 0;
1783                sample->tid = event->mmap2.tid;
1784                sample->pid = event->mmap2.pid;
1785        }
1786        print_sample_start(sample, thread, evsel);
1787        perf_event__fprintf(event, stdout);
1788        thread__put(thread);
1789        return 0;
1790}
1791
1792static int process_switch_event(struct perf_tool *tool,
1793                                union perf_event *event,
1794                                struct perf_sample *sample,
1795                                struct machine *machine)
1796{
1797        struct thread *thread;
1798        struct perf_script *script = container_of(tool, struct perf_script, tool);
1799        struct perf_session *session = script->session;
1800        struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1801
1802        if (perf_event__process_switch(tool, event, sample, machine) < 0)
1803                return -1;
1804
1805        thread = machine__findnew_thread(machine, sample->pid,
1806                                         sample->tid);
1807        if (thread == NULL) {
1808                pr_debug("problem processing SWITCH event, skipping it.\n");
1809                return -1;
1810        }
1811
1812        print_sample_start(sample, thread, evsel);
1813        perf_event__fprintf(event, stdout);
1814        thread__put(thread);
1815        return 0;
1816}
1817
1818static void sig_handler(int sig __maybe_unused)
1819{
1820        session_done = 1;
1821}
1822
1823static int __cmd_script(struct perf_script *script)
1824{
1825        int ret;
1826
1827        signal(SIGINT, sig_handler);
1828
1829        /* override event processing functions */
1830        if (script->show_task_events) {
1831                script->tool.comm = process_comm_event;
1832                script->tool.fork = process_fork_event;
1833                script->tool.exit = process_exit_event;
1834        }
1835        if (script->show_mmap_events) {
1836                script->tool.mmap = process_mmap_event;
1837                script->tool.mmap2 = process_mmap2_event;
1838        }
1839        if (script->show_switch_events)
1840                script->tool.context_switch = process_switch_event;
1841        if (script->show_namespace_events)
1842                script->tool.namespaces = process_namespaces_event;
1843
1844        ret = perf_session__process_events(script->session);
1845
1846        if (debug_mode)
1847                pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
1848
1849        return ret;
1850}
1851
1852struct script_spec {
1853        struct list_head        node;
1854        struct scripting_ops    *ops;
1855        char                    spec[0];
1856};
1857
1858static LIST_HEAD(script_specs);
1859
1860static struct script_spec *script_spec__new(const char *spec,
1861                                            struct scripting_ops *ops)
1862{
1863        struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
1864
1865        if (s != NULL) {
1866                strcpy(s->spec, spec);
1867                s->ops = ops;
1868        }
1869
1870        return s;
1871}
1872
1873static void script_spec__add(struct script_spec *s)
1874{
1875        list_add_tail(&s->node, &script_specs);
1876}
1877
1878static struct script_spec *script_spec__find(const char *spec)
1879{
1880        struct script_spec *s;
1881
1882        list_for_each_entry(s, &script_specs, node)
1883                if (strcasecmp(s->spec, spec) == 0)
1884                        return s;
1885        return NULL;
1886}
1887
1888int script_spec_register(const char *spec, struct scripting_ops *ops)
1889{
1890        struct script_spec *s;
1891
1892        s = script_spec__find(spec);
1893        if (s)
1894                return -1;
1895
1896        s = script_spec__new(spec, ops);
1897        if (!s)
1898                return -1;
1899        else
1900                script_spec__add(s);
1901
1902        return 0;
1903}
1904
1905static struct scripting_ops *script_spec__lookup(const char *spec)
1906{
1907        struct script_spec *s = script_spec__find(spec);
1908        if (!s)
1909                return NULL;
1910
1911        return s->ops;
1912}
1913
1914static void list_available_languages(void)
1915{
1916        struct script_spec *s;
1917
1918        fprintf(stderr, "\n");
1919        fprintf(stderr, "Scripting language extensions (used in "
1920                "perf script -s [spec:]script.[spec]):\n\n");
1921
1922        list_for_each_entry(s, &script_specs, node)
1923                fprintf(stderr, "  %-42s [%s]\n", s->spec, s->ops->name);
1924
1925        fprintf(stderr, "\n");
1926}
1927
1928static int parse_scriptname(const struct option *opt __maybe_unused,
1929                            const char *str, int unset __maybe_unused)
1930{
1931        char spec[PATH_MAX];
1932        const char *script, *ext;
1933        int len;
1934
1935        if (strcmp(str, "lang") == 0) {
1936                list_available_languages();
1937                exit(0);
1938        }
1939
1940        script = strchr(str, ':');
1941        if (script) {
1942                len = script - str;
1943                if (len >= PATH_MAX) {
1944                        fprintf(stderr, "invalid language specifier");
1945                        return -1;
1946                }
1947                strncpy(spec, str, len);
1948                spec[len] = '\0';
1949                scripting_ops = script_spec__lookup(spec);
1950                if (!scripting_ops) {
1951                        fprintf(stderr, "invalid language specifier");
1952                        return -1;
1953                }
1954                script++;
1955        } else {
1956                script = str;
1957                ext = strrchr(script, '.');
1958                if (!ext) {
1959                        fprintf(stderr, "invalid script extension");
1960                        return -1;
1961                }
1962                scripting_ops = script_spec__lookup(++ext);
1963                if (!scripting_ops) {
1964                        fprintf(stderr, "invalid script extension");
1965                        return -1;
1966                }
1967        }
1968
1969        script_name = strdup(script);
1970
1971        return 0;
1972}
1973
1974static int parse_output_fields(const struct option *opt __maybe_unused,
1975                            const char *arg, int unset __maybe_unused)
1976{
1977        char *tok, *strtok_saveptr = NULL;
1978        int i, imax = ARRAY_SIZE(all_output_options);
1979        int j;
1980        int rc = 0;
1981        char *str = strdup(arg);
1982        int type = -1;
1983        enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;
1984
1985        if (!str)
1986                return -ENOMEM;
1987
1988        /* first word can state for which event type the user is specifying
1989         * the fields. If no type exists, the specified fields apply to all
1990         * event types found in the file minus the invalid fields for a type.
1991         */
1992        tok = strchr(str, ':');
1993        if (tok) {
1994                *tok = '\0';
1995                tok++;
1996                if (!strcmp(str, "hw"))
1997                        type = PERF_TYPE_HARDWARE;
1998                else if (!strcmp(str, "sw"))
1999                        type = PERF_TYPE_SOFTWARE;
2000                else if (!strcmp(str, "trace"))
2001                        type = PERF_TYPE_TRACEPOINT;
2002                else if (!strcmp(str, "raw"))
2003                        type = PERF_TYPE_RAW;
2004                else if (!strcmp(str, "break"))
2005                        type = PERF_TYPE_BREAKPOINT;
2006                else if (!strcmp(str, "synth"))
2007                        type = OUTPUT_TYPE_SYNTH;
2008                else {
2009                        fprintf(stderr, "Invalid event type in field string.\n");
2010                        rc = -EINVAL;
2011                        goto out;
2012                }
2013
2014                if (output[type].user_set)
2015                        pr_warning("Overriding previous field request for %s events.\n",
2016                                   event_type(type));
2017
2018                output[type].fields = 0;
2019                output[type].user_set = true;
2020                output[type].wildcard_set = false;
2021
2022        } else {
2023                tok = str;
2024                if (strlen(str) == 0) {
2025                        fprintf(stderr,
2026                                "Cannot set fields to 'none' for all event types.\n");
2027                        rc = -EINVAL;
2028                        goto out;
2029                }
2030
2031                /* Don't override defaults for +- */
2032                if (strchr(str, '+') || strchr(str, '-'))
2033                        goto parse;
2034
2035                if (output_set_by_user())
2036                        pr_warning("Overriding previous field request for all events.\n");
2037
2038                for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2039                        output[j].fields = 0;
2040                        output[j].user_set = true;
2041                        output[j].wildcard_set = true;
2042                }
2043        }
2044
2045parse:
2046        for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
2047                if (*tok == '+') {
2048                        if (change == SET)
2049                                goto out_badmix;
2050                        change = ADD;
2051                        tok++;
2052                } else if (*tok == '-') {
2053                        if (change == SET)
2054                                goto out_badmix;
2055                        change = REMOVE;
2056                        tok++;
2057                } else {
2058                        if (change != SET && change != DEFAULT)
2059                                goto out_badmix;
2060                        change = SET;
2061                }
2062
2063                for (i = 0; i < imax; ++i) {
2064                        if (strcmp(tok, all_output_options[i].str) == 0)
2065                                break;
2066                }
2067                if (i == imax && strcmp(tok, "flags") == 0) {
2068                        print_flags = change == REMOVE ? false : true;
2069                        continue;
2070                }
2071                if (i == imax) {
2072                        fprintf(stderr, "Invalid field requested.\n");
2073                        rc = -EINVAL;
2074                        goto out;
2075                }
2076
2077                if (type == -1) {
2078                        /* add user option to all events types for
2079                         * which it is valid
2080                         */
2081                        for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2082                                if (output[j].invalid_fields & all_output_options[i].field) {
2083                                        pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
2084                                                   all_output_options[i].str, event_type(j));
2085                                } else {
2086                                        if (change == REMOVE)
2087                                                output[j].fields &= ~all_output_options[i].field;
2088                                        else
2089                                                output[j].fields |= all_output_options[i].field;
2090                                }
2091                        }
2092                } else {
2093                        if (output[type].invalid_fields & all_output_options[i].field) {
2094                                fprintf(stderr, "\'%s\' not valid for %s events.\n",
2095                                         all_output_options[i].str, event_type(type));
2096
2097                                rc = -EINVAL;
2098                                goto out;
2099                        }
2100                        output[type].fields |= all_output_options[i].field;
2101                }
2102        }
2103
2104        if (type >= 0) {
2105                if (output[type].fields == 0) {
2106                        pr_debug("No fields requested for %s type. "
2107                                 "Events will not be displayed.\n", event_type(type));
2108                }
2109        }
2110        goto out;
2111
2112out_badmix:
2113        fprintf(stderr, "Cannot mix +-field with overridden fields\n");
2114        rc = -EINVAL;
2115out:
2116        free(str);
2117        return rc;
2118}
2119
2120/* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */
2121static int is_directory(const char *base_path, const struct dirent *dent)
2122{
2123        char path[PATH_MAX];
2124        struct stat st;
2125
2126        sprintf(path, "%s/%s", base_path, dent->d_name);
2127        if (stat(path, &st))
2128                return 0;
2129
2130        return S_ISDIR(st.st_mode);
2131}
2132
2133#define for_each_lang(scripts_path, scripts_dir, lang_dirent)           \
2134        while ((lang_dirent = readdir(scripts_dir)) != NULL)            \
2135                if ((lang_dirent->d_type == DT_DIR ||                   \
2136                     (lang_dirent->d_type == DT_UNKNOWN &&              \
2137                      is_directory(scripts_path, lang_dirent))) &&      \
2138                    (strcmp(lang_dirent->d_name, ".")) &&               \
2139                    (strcmp(lang_dirent->d_name, "..")))
2140
2141#define for_each_script(lang_path, lang_dir, script_dirent)             \
2142        while ((script_dirent = readdir(lang_dir)) != NULL)             \
2143                if (script_dirent->d_type != DT_DIR &&                  \
2144                    (script_dirent->d_type != DT_UNKNOWN ||             \
2145                     !is_directory(lang_path, script_dirent)))
2146
2147
2148#define RECORD_SUFFIX                   "-record"
2149#define REPORT_SUFFIX                   "-report"
2150
2151struct script_desc {
2152        struct list_head        node;
2153        char                    *name;
2154        char                    *half_liner;
2155        char                    *args;
2156};
2157
2158static LIST_HEAD(script_descs);
2159
2160static struct script_desc *script_desc__new(const char *name)
2161{
2162        struct script_desc *s = zalloc(sizeof(*s));
2163
2164        if (s != NULL && name)
2165                s->name = strdup(name);
2166
2167        return s;
2168}
2169
2170static void script_desc__delete(struct script_desc *s)
2171{
2172        zfree(&s->name);
2173        zfree(&s->half_liner);
2174        zfree(&s->args);
2175        free(s);
2176}
2177
2178static void script_desc__add(struct script_desc *s)
2179{
2180        list_add_tail(&s->node, &script_descs);
2181}
2182
2183static struct script_desc *script_desc__find(const char *name)
2184{
2185        struct script_desc *s;
2186
2187        list_for_each_entry(s, &script_descs, node)
2188                if (strcasecmp(s->name, name) == 0)
2189                        return s;
2190        return NULL;
2191}
2192
2193static struct script_desc *script_desc__findnew(const char *name)
2194{
2195        struct script_desc *s = script_desc__find(name);
2196
2197        if (s)
2198                return s;
2199
2200        s = script_desc__new(name);
2201        if (!s)
2202                goto out_delete_desc;
2203
2204        script_desc__add(s);
2205
2206        return s;
2207
2208out_delete_desc:
2209        script_desc__delete(s);
2210
2211        return NULL;
2212}
2213
2214static const char *ends_with(const char *str, const char *suffix)
2215{
2216        size_t suffix_len = strlen(suffix);
2217        const char *p = str;
2218
2219        if (strlen(str) > suffix_len) {
2220                p = str + strlen(str) - suffix_len;
2221                if (!strncmp(p, suffix, suffix_len))
2222                        return p;
2223        }
2224
2225        return NULL;
2226}
2227
2228static int read_script_info(struct script_desc *desc, const char *filename)
2229{
2230        char line[BUFSIZ], *p;
2231        FILE *fp;
2232
2233        fp = fopen(filename, "r");
2234        if (!fp)
2235                return -1;
2236
2237        while (fgets(line, sizeof(line), fp)) {
2238                p = ltrim(line);
2239                if (strlen(p) == 0)
2240                        continue;
2241                if (*p != '#')
2242                        continue;
2243                p++;
2244                if (strlen(p) && *p == '!')
2245                        continue;
2246
2247                p = ltrim(p);
2248                if (strlen(p) && p[strlen(p) - 1] == '\n')
2249                        p[strlen(p) - 1] = '\0';
2250
2251                if (!strncmp(p, "description:", strlen("description:"))) {
2252                        p += strlen("description:");
2253                        desc->half_liner = strdup(ltrim(p));
2254                        continue;
2255                }
2256
2257                if (!strncmp(p, "args:", strlen("args:"))) {
2258                        p += strlen("args:");
2259                        desc->args = strdup(ltrim(p));
2260                        continue;
2261                }
2262        }
2263
2264        fclose(fp);
2265
2266        return 0;
2267}
2268
2269static char *get_script_root(struct dirent *script_dirent, const char *suffix)
2270{
2271        char *script_root, *str;
2272
2273        script_root = strdup(script_dirent->d_name);
2274        if (!script_root)
2275                return NULL;
2276
2277        str = (char *)ends_with(script_root, suffix);
2278        if (!str) {
2279                free(script_root);
2280                return NULL;
2281        }
2282
2283        *str = '\0';
2284        return script_root;
2285}
2286
2287static int list_available_scripts(const struct option *opt __maybe_unused,
2288                                  const char *s __maybe_unused,
2289                                  int unset __maybe_unused)
2290{
2291        struct dirent *script_dirent, *lang_dirent;
2292        char scripts_path[MAXPATHLEN];
2293        DIR *scripts_dir, *lang_dir;
2294        char script_path[MAXPATHLEN];
2295        char lang_path[MAXPATHLEN];
2296        struct script_desc *desc;
2297        char first_half[BUFSIZ];
2298        char *script_root;
2299
2300        snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
2301
2302        scripts_dir = opendir(scripts_path);
2303        if (!scripts_dir) {
2304                fprintf(stdout,
2305                        "open(%s) failed.\n"
2306                        "Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",
2307                        scripts_path);
2308                exit(-1);
2309        }
2310
2311        for_each_lang(scripts_path, scripts_dir, lang_dirent) {
2312                snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
2313                         lang_dirent->d_name);
2314                lang_dir = opendir(lang_path);
2315                if (!lang_dir)
2316                        continue;
2317
2318                for_each_script(lang_path, lang_dir, script_dirent) {
2319                        script_root = get_script_root(script_dirent, REPORT_SUFFIX);
2320                        if (script_root) {
2321                                desc = script_desc__findnew(script_root);
2322                                snprintf(script_path, MAXPATHLEN, "%s/%s",
2323                                         lang_path, script_dirent->d_name);
2324                                read_script_info(desc, script_path);
2325                                free(script_root);
2326                        }
2327                }
2328        }
2329
2330        fprintf(stdout, "List of available trace scripts:\n");
2331        list_for_each_entry(desc, &script_descs, node) {
2332                sprintf(first_half, "%s %s", desc->name,
2333                        desc->args ? desc->args : "");
2334                fprintf(stdout, "  %-36s %s\n", first_half,
2335                        desc->half_liner ? desc->half_liner : "");
2336        }
2337
2338        exit(0);
2339}
2340
2341/*
2342 * Some scripts specify the required events in their "xxx-record" file,
2343 * this function will check if the events in perf.data match those
2344 * mentioned in the "xxx-record".
2345 *
2346 * Fixme: All existing "xxx-record" are all in good formats "-e event ",
2347 * which is covered well now. And new parsing code should be added to
2348 * cover the future complexing formats like event groups etc.
2349 */
2350static int check_ev_match(char *dir_name, char *scriptname,
2351                        struct perf_session *session)
2352{
2353        char filename[MAXPATHLEN], evname[128];
2354        char line[BUFSIZ], *p;
2355        struct perf_evsel *pos;
2356        int match, len;
2357        FILE *fp;
2358
2359        sprintf(filename, "%s/bin/%s-record", dir_name, scriptname);
2360
2361        fp = fopen(filename, "r");
2362        if (!fp)
2363                return -1;
2364
2365        while (fgets(line, sizeof(line), fp)) {
2366                p = ltrim(line);
2367                if (*p == '#')
2368                        continue;
2369
2370                while (strlen(p)) {
2371                        p = strstr(p, "-e");
2372                        if (!p)
2373                                break;
2374
2375                        p += 2;
2376                        p = ltrim(p);
2377                        len = strcspn(p, " \t");
2378                        if (!len)
2379                                break;
2380
2381                        snprintf(evname, len + 1, "%s", p);
2382
2383                        match = 0;
2384                        evlist__for_each_entry(session->evlist, pos) {
2385                                if (!strcmp(perf_evsel__name(pos), evname)) {
2386                                        match = 1;
2387                                        break;
2388                                }
2389                        }
2390
2391                        if (!match) {
2392                                fclose(fp);
2393                                return -1;
2394                        }
2395                }
2396        }
2397
2398        fclose(fp);
2399        return 0;
2400}
2401
2402/*
2403 * Return -1 if none is found, otherwise the actual scripts number.
2404 *
2405 * Currently the only user of this function is the script browser, which
2406 * will list all statically runnable scripts, select one, execute it and
2407 * show the output in a perf browser.
2408 */
2409int find_scripts(char **scripts_array, char **scripts_path_array)
2410{
2411        struct dirent *script_dirent, *lang_dirent;
2412        char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
2413        DIR *scripts_dir, *lang_dir;
2414        struct perf_session *session;
2415        struct perf_data_file file = {
2416                .path = input_name,
2417                .mode = PERF_DATA_MODE_READ,
2418        };
2419        char *temp;
2420        int i = 0;
2421
2422        session = perf_session__new(&file, false, NULL);
2423        if (!session)
2424                return -1;
2425
2426        snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
2427
2428        scripts_dir = opendir(scripts_path);
2429        if (!scripts_dir) {
2430                perf_session__delete(session);
2431                return -1;
2432        }
2433
2434        for_each_lang(scripts_path, scripts_dir, lang_dirent) {
2435                snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
2436                         lang_dirent->d_name);
2437#ifdef NO_LIBPERL
2438                if (strstr(lang_path, "perl"))
2439                        continue;
2440#endif
2441#ifdef NO_LIBPYTHON
2442                if (strstr(lang_path, "python"))
2443                        continue;
2444#endif
2445
2446                lang_dir = opendir(lang_path);
2447                if (!lang_dir)
2448                        continue;
2449
2450                for_each_script(lang_path, lang_dir, script_dirent) {
2451                        /* Skip those real time scripts: xxxtop.p[yl] */
2452                        if (strstr(script_dirent->d_name, "top."))
2453                                continue;
2454                        sprintf(scripts_path_array[i], "%s/%s", lang_path,
2455                                script_dirent->d_name);
2456                        temp = strchr(script_dirent->d_name, '.');
2457                        snprintf(scripts_array[i],
2458                                (temp - script_dirent->d_name) + 1,
2459                                "%s", script_dirent->d_name);
2460
2461                        if (check_ev_match(lang_path,
2462                                        scripts_array[i], session))
2463                                continue;
2464
2465                        i++;
2466                }
2467                closedir(lang_dir);
2468        }
2469
2470        closedir(scripts_dir);
2471        perf_session__delete(session);
2472        return i;
2473}
2474
2475static char *get_script_path(const char *script_root, const char *suffix)
2476{
2477        struct dirent *script_dirent, *lang_dirent;
2478        char scripts_path[MAXPATHLEN];
2479        char script_path[MAXPATHLEN];
2480        DIR *scripts_dir, *lang_dir;
2481        char lang_path[MAXPATHLEN];
2482        char *__script_root;
2483
2484        snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
2485
2486        scripts_dir = opendir(scripts_path);
2487        if (!scripts_dir)
2488                return NULL;
2489
2490        for_each_lang(scripts_path, scripts_dir, lang_dirent) {
2491                snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
2492                         lang_dirent->d_name);
2493                lang_dir = opendir(lang_path);
2494                if (!lang_dir)
2495                        continue;
2496
2497                for_each_script(lang_path, lang_dir, script_dirent) {
2498                        __script_root = get_script_root(script_dirent, suffix);
2499                        if (__script_root && !strcmp(script_root, __script_root)) {
2500                                free(__script_root);
2501                                closedir(lang_dir);
2502                                closedir(scripts_dir);
2503                                snprintf(script_path, MAXPATHLEN, "%s/%s",
2504                                         lang_path, script_dirent->d_name);
2505                                return strdup(script_path);
2506                        }
2507                        free(__script_root);
2508                }
2509                closedir(lang_dir);
2510        }
2511        closedir(scripts_dir);
2512
2513        return NULL;
2514}
2515
2516static bool is_top_script(const char *script_path)
2517{
2518        return ends_with(script_path, "top") == NULL ? false : true;
2519}
2520
2521static int has_required_arg(char *script_path)
2522{
2523        struct script_desc *desc;
2524        int n_args = 0;
2525        char *p;
2526
2527        desc = script_desc__new(NULL);
2528
2529        if (read_script_info(desc, script_path))
2530                goto out;
2531
2532        if (!desc->args)
2533                goto out;
2534
2535        for (p = desc->args; *p; p++)
2536                if (*p == '<')
2537                        n_args++;
2538out:
2539        script_desc__delete(desc);
2540
2541        return n_args;
2542}
2543
2544static int have_cmd(int argc, const char **argv)
2545{
2546        char **__argv = malloc(sizeof(const char *) * argc);
2547
2548        if (!__argv) {
2549                pr_err("malloc failed\n");
2550                return -1;
2551        }
2552
2553        memcpy(__argv, argv, sizeof(const char *) * argc);
2554        argc = parse_options(argc, (const char **)__argv, record_options,
2555                             NULL, PARSE_OPT_STOP_AT_NON_OPTION);
2556        free(__argv);
2557
2558        system_wide = (argc == 0);
2559
2560        return 0;
2561}
2562
2563static void script__setup_sample_type(struct perf_script *script)
2564{
2565        struct perf_session *session = script->session;
2566        u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
2567
2568        if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
2569                if ((sample_type & PERF_SAMPLE_REGS_USER) &&
2570                    (sample_type & PERF_SAMPLE_STACK_USER))
2571                        callchain_param.record_mode = CALLCHAIN_DWARF;
2572                else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
2573                        callchain_param.record_mode = CALLCHAIN_LBR;
2574                else
2575                        callchain_param.record_mode = CALLCHAIN_FP;
2576        }
2577}
2578
2579static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
2580                                    union perf_event *event,
2581                                    struct perf_session *session)
2582{
2583        struct stat_round_event *round = &event->stat_round;
2584        struct perf_evsel *counter;
2585
2586        evlist__for_each_entry(session->evlist, counter) {
2587                perf_stat_process_counter(&stat_config, counter);
2588                process_stat(counter, round->time);
2589        }
2590
2591        process_stat_interval(round->time);
2592        return 0;
2593}
2594
2595static int process_stat_config_event(struct perf_tool *tool __maybe_unused,
2596                                     union perf_event *event,
2597                                     struct perf_session *session __maybe_unused)
2598{
2599        perf_event__read_stat_config(&stat_config, &event->stat_config);
2600        return 0;
2601}
2602
2603static int set_maps(struct perf_script *script)
2604{
2605        struct perf_evlist *evlist = script->session->evlist;
2606
2607        if (!script->cpus || !script->threads)
2608                return 0;
2609
2610        if (WARN_ONCE(script->allocated, "stats double allocation\n"))
2611                return -EINVAL;
2612
2613        perf_evlist__set_maps(evlist, script->cpus, script->threads);
2614
2615        if (perf_evlist__alloc_stats(evlist, true))
2616                return -ENOMEM;
2617
2618        script->allocated = true;
2619        return 0;
2620}
2621
2622static
2623int process_thread_map_event(struct perf_tool *tool,
2624                             union perf_event *event,
2625                             struct perf_session *session __maybe_unused)
2626{
2627        struct perf_script *script = container_of(tool, struct perf_script, tool);
2628
2629        if (script->threads) {
2630                pr_warning("Extra thread map event, ignoring.\n");
2631                return 0;
2632        }
2633
2634        script->threads = thread_map__new_event(&event->thread_map);
2635        if (!script->threads)
2636                return -ENOMEM;
2637
2638        return set_maps(script);
2639}
2640
2641static
2642int process_cpu_map_event(struct perf_tool *tool __maybe_unused,
2643                          union perf_event *event,
2644                          struct perf_session *session __maybe_unused)
2645{
2646        struct perf_script *script = container_of(tool, struct perf_script, tool);
2647
2648        if (script->cpus) {
2649                pr_warning("Extra cpu map event, ignoring.\n");
2650                return 0;
2651        }
2652
2653        script->cpus = cpu_map__new_data(&event->cpu_map.data);
2654        if (!script->cpus)
2655                return -ENOMEM;
2656
2657        return set_maps(script);
2658}
2659
2660int cmd_script(int argc, const char **argv)
2661{
2662        bool show_full_info = false;
2663        bool header = false;
2664        bool header_only = false;
2665        bool script_started = false;
2666        char *rec_script_path = NULL;
2667        char *rep_script_path = NULL;
2668        struct perf_session *session;
2669        struct itrace_synth_opts itrace_synth_opts = { .set = false, };
2670        char *script_path = NULL;
2671        const char **__argv;
2672        int i, j, err = 0;
2673        struct perf_script script = {
2674                .tool = {
2675                        .sample          = process_sample_event,
2676                        .mmap            = perf_event__process_mmap,
2677                        .mmap2           = perf_event__process_mmap2,
2678                        .comm            = perf_event__process_comm,
2679                        .namespaces      = perf_event__process_namespaces,
2680                        .exit            = perf_event__process_exit,
2681                        .fork            = perf_event__process_fork,
2682                        .attr            = process_attr,
2683                        .event_update   = perf_event__process_event_update,
2684                        .tracing_data    = perf_event__process_tracing_data,
2685                        .build_id        = perf_event__process_build_id,
2686                        .id_index        = perf_event__process_id_index,
2687                        .auxtrace_info   = perf_event__process_auxtrace_info,
2688                        .auxtrace        = perf_event__process_auxtrace,
2689                        .auxtrace_error  = perf_event__process_auxtrace_error,
2690                        .stat            = perf_event__process_stat_event,
2691                        .stat_round      = process_stat_round_event,
2692                        .stat_config     = process_stat_config_event,
2693                        .thread_map      = process_thread_map_event,
2694                        .cpu_map         = process_cpu_map_event,
2695                        .ordered_events  = true,
2696                        .ordering_requires_timestamps = true,
2697                },
2698        };
2699        struct perf_data_file file = {
2700                .mode = PERF_DATA_MODE_READ,
2701        };
2702        const struct option options[] = {
2703        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
2704                    "dump raw trace in ASCII"),
2705        OPT_INCR('v', "verbose", &verbose,
2706                 "be more verbose (show symbol address, etc)"),
2707        OPT_BOOLEAN('L', "Latency", &latency_format,
2708                    "show latency attributes (irqs/preemption disabled, etc)"),
2709        OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
2710                           list_available_scripts),
2711        OPT_CALLBACK('s', "script", NULL, "name",
2712                     "script file name (lang:script name, script name, or *)",
2713                     parse_scriptname),
2714        OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
2715                   "generate perf-script.xx script in specified language"),
2716        OPT_STRING('i', "input", &input_name, "file", "input file name"),
2717        OPT_BOOLEAN('d', "debug-mode", &debug_mode,
2718                   "do various checks like samples ordering and lost events"),
2719        OPT_BOOLEAN(0, "header", &header, "Show data header."),
2720        OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),
2721        OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
2722                   "file", "vmlinux pathname"),
2723        OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
2724                   "file", "kallsyms pathname"),
2725        OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
2726                    "When printing symbols do not display call chain"),
2727        OPT_CALLBACK(0, "symfs", NULL, "directory",
2728                     "Look for files with symbols relative to this directory",
2729                     symbol__config_symfs),
2730        OPT_CALLBACK('F', "fields", NULL, "str",
2731                     "comma separated output fields prepend with 'type:'. "
2732                     "+field to add and -field to remove."
2733                     "Valid types: hw,sw,trace,raw,synth. "
2734                     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
2735                     "addr,symoff,period,iregs,brstack,brstacksym,flags,"
2736                     "bpf-output,callindent,insn,insnlen,brstackinsn,synth",
2737                     parse_output_fields),
2738        OPT_BOOLEAN('a', "all-cpus", &system_wide,
2739                    "system-wide collection from all CPUs"),
2740        OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
2741                   "only consider these symbols"),
2742        OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]",
2743                   "Stop display of callgraph at these symbols"),
2744        OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
2745        OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
2746                   "only display events for these comms"),
2747        OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
2748                   "only consider symbols in these pids"),
2749        OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
2750                   "only consider symbols in these tids"),
2751        OPT_UINTEGER(0, "max-stack", &scripting_max_stack,
2752                     "Set the maximum stack depth when parsing the callchain, "
2753                     "anything beyond the specified depth will be ignored. "
2754                     "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
2755        OPT_BOOLEAN('I', "show-info", &show_full_info,
2756                    "display extended information from perf.data file"),
2757        OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
2758                    "Show the path of [kernel.kallsyms]"),
2759        OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events,
2760                    "Show the fork/comm/exit events"),
2761        OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
2762                    "Show the mmap events"),
2763        OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
2764                    "Show context switch events (if recorded)"),
2765        OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
2766                    "Show namespace events (if recorded)"),
2767        OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
2768        OPT_INTEGER(0, "max-blocks", &max_blocks,
2769                    "Maximum number of code blocks to dump with brstackinsn"),
2770        OPT_BOOLEAN(0, "ns", &nanosecs,
2771                    "Use 9 decimal places when displaying time"),
2772        OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
2773                            "Instruction Tracing options",
2774                            itrace_parse_synth_opts),
2775        OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
2776                        "Show full source file name path for source lines"),
2777        OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
2778                        "Enable symbol demangling"),
2779        OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
2780                        "Enable kernel symbol demangling"),
2781        OPT_STRING(0, "time", &script.time_str, "str",
2782                   "Time span of interest (start,stop)"),
2783        OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
2784                    "Show inline function"),
2785        OPT_END()
2786        };
2787        const char * const script_subcommands[] = { "record", "report", NULL };
2788        const char *script_usage[] = {
2789                "perf script [<options>]",
2790                "perf script [<options>] record <script> [<record-options>] <command>",
2791                "perf script [<options>] report <script> [script-args]",
2792                "perf script [<options>] <script> [<record-options>] <command>",
2793                "perf script [<options>] <top-script> [script-args]",
2794                NULL
2795        };
2796
2797        setup_scripting();
2798
2799        argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
2800                             PARSE_OPT_STOP_AT_NON_OPTION);
2801
2802        file.path = input_name;
2803        file.force = symbol_conf.force;
2804
2805        if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
2806                rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
2807                if (!rec_script_path)
2808                        return cmd_record(argc, argv);
2809        }
2810
2811        if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
2812                rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
2813                if (!rep_script_path) {
2814                        fprintf(stderr,
2815                                "Please specify a valid report script"
2816                                "(see 'perf script -l' for listing)\n");
2817                        return -1;
2818                }
2819        }
2820
2821        if (itrace_synth_opts.callchain &&
2822            itrace_synth_opts.callchain_sz > scripting_max_stack)
2823                scripting_max_stack = itrace_synth_opts.callchain_sz;
2824
2825        /* make sure PERF_EXEC_PATH is set for scripts */
2826        set_argv_exec_path(get_argv_exec_path());
2827
2828        if (argc && !script_name && !rec_script_path && !rep_script_path) {
2829                int live_pipe[2];
2830                int rep_args;
2831                pid_t pid;
2832
2833                rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);
2834                rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
2835
2836                if (!rec_script_path && !rep_script_path) {
2837                        usage_with_options_msg(script_usage, options,
2838                                "Couldn't find script `%s'\n\n See perf"
2839                                " script -l for available scripts.\n", argv[0]);
2840                }
2841
2842                if (is_top_script(argv[0])) {
2843                        rep_args = argc - 1;
2844                } else {
2845                        int rec_args;
2846
2847                        rep_args = has_required_arg(rep_script_path);
2848                        rec_args = (argc - 1) - rep_args;
2849                        if (rec_args < 0) {
2850                                usage_with_options_msg(script_usage, options,
2851                                        "`%s' script requires options."
2852                                        "\n\n See perf script -l for available "
2853                                        "scripts and options.\n", argv[0]);
2854                        }
2855                }
2856
2857                if (pipe(live_pipe) < 0) {
2858                        perror("failed to create pipe");
2859                        return -1;
2860                }
2861
2862                pid = fork();
2863                if (pid < 0) {
2864                        perror("failed to fork");
2865                        return -1;
2866                }
2867
2868                if (!pid) {
2869                        j = 0;
2870
2871                        dup2(live_pipe[1], 1);
2872                        close(live_pipe[0]);
2873
2874                        if (is_top_script(argv[0])) {
2875                                system_wide = true;
2876                        } else if (!system_wide) {
2877                                if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
2878                                        err = -1;
2879                                        goto out;
2880                                }
2881                        }
2882
2883                        __argv = malloc((argc + 6) * sizeof(const char *));
2884                        if (!__argv) {
2885                                pr_err("malloc failed\n");
2886                                err = -ENOMEM;
2887                                goto out;
2888                        }
2889
2890                        __argv[j++] = "/bin/sh";
2891                        __argv[j++] = rec_script_path;
2892                        if (system_wide)
2893                                __argv[j++] = "-a";
2894                        __argv[j++] = "-q";
2895                        __argv[j++] = "-o";
2896                        __argv[j++] = "-";
2897                        for (i = rep_args + 1; i < argc; i++)
2898                                __argv[j++] = argv[i];
2899                        __argv[j++] = NULL;
2900
2901                        execvp("/bin/sh", (char **)__argv);
2902                        free(__argv);
2903                        exit(-1);
2904                }
2905
2906                dup2(live_pipe[0], 0);
2907                close(live_pipe[1]);
2908
2909                __argv = malloc((argc + 4) * sizeof(const char *));
2910                if (!__argv) {
2911                        pr_err("malloc failed\n");
2912                        err = -ENOMEM;
2913                        goto out;
2914                }
2915
2916                j = 0;
2917                __argv[j++] = "/bin/sh";
2918                __argv[j++] = rep_script_path;
2919                for (i = 1; i < rep_args + 1; i++)
2920                        __argv[j++] = argv[i];
2921                __argv[j++] = "-i";
2922                __argv[j++] = "-";
2923                __argv[j++] = NULL;
2924
2925                execvp("/bin/sh", (char **)__argv);
2926                free(__argv);
2927                exit(-1);
2928        }
2929
2930        if (rec_script_path)
2931                script_path = rec_script_path;
2932        if (rep_script_path)
2933                script_path = rep_script_path;
2934
2935        if (script_path) {
2936                j = 0;
2937
2938                if (!rec_script_path)
2939                        system_wide = false;
2940                else if (!system_wide) {
2941                        if (have_cmd(argc - 1, &argv[1]) != 0) {
2942                                err = -1;
2943                                goto out;
2944                        }
2945                }
2946
2947                __argv = malloc((argc + 2) * sizeof(const char *));
2948                if (!__argv) {
2949                        pr_err("malloc failed\n");
2950                        err = -ENOMEM;
2951                        goto out;
2952                }
2953
2954                __argv[j++] = "/bin/sh";
2955                __argv[j++] = script_path;
2956                if (system_wide)
2957                        __argv[j++] = "-a";
2958                for (i = 2; i < argc; i++)
2959                        __argv[j++] = argv[i];
2960                __argv[j++] = NULL;
2961
2962                execvp("/bin/sh", (char **)__argv);
2963                free(__argv);
2964                exit(-1);
2965        }
2966
2967        if (!script_name)
2968                setup_pager();
2969
2970        session = perf_session__new(&file, false, &script.tool);
2971        if (session == NULL)
2972                return -1;
2973
2974        if (header || header_only) {
2975                perf_session__fprintf_info(session, stdout, show_full_info);
2976                if (header_only)
2977                        goto out_delete;
2978        }
2979
2980        if (symbol__init(&session->header.env) < 0)
2981                goto out_delete;
2982
2983        script.session = session;
2984        script__setup_sample_type(&script);
2985
2986        if (output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT)
2987                itrace_synth_opts.thread_stack = true;
2988
2989        session->itrace_synth_opts = &itrace_synth_opts;
2990
2991        if (cpu_list) {
2992                err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
2993                if (err < 0)
2994                        goto out_delete;
2995                itrace_synth_opts.cpu_bitmap = cpu_bitmap;
2996        }
2997
2998        if (!no_callchain)
2999                symbol_conf.use_callchain = true;
3000        else
3001                symbol_conf.use_callchain = false;
3002
3003        if (session->tevent.pevent &&
3004            pevent_set_function_resolver(session->tevent.pevent,
3005                                         machine__resolve_kernel_addr,
3006                                         &session->machines.host) < 0) {
3007                pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
3008                return -1;
3009        }
3010
3011        if (generate_script_lang) {
3012                struct stat perf_stat;
3013                int input;
3014
3015                if (output_set_by_user()) {
3016                        fprintf(stderr,
3017                                "custom fields not supported for generated scripts");
3018                        err = -EINVAL;
3019                        goto out_delete;
3020                }
3021
3022                input = open(file.path, O_RDONLY);      /* input_name */
3023                if (input < 0) {
3024                        err = -errno;
3025                        perror("failed to open file");
3026                        goto out_delete;
3027                }
3028
3029                err = fstat(input, &perf_stat);
3030                if (err < 0) {
3031                        perror("failed to stat file");
3032                        goto out_delete;
3033                }
3034
3035                if (!perf_stat.st_size) {
3036                        fprintf(stderr, "zero-sized file, nothing to do!\n");
3037                        goto out_delete;
3038                }
3039
3040                scripting_ops = script_spec__lookup(generate_script_lang);
3041                if (!scripting_ops) {
3042                        fprintf(stderr, "invalid language specifier");
3043                        err = -ENOENT;
3044                        goto out_delete;
3045                }
3046
3047                err = scripting_ops->generate_script(session->tevent.pevent,
3048                                                     "perf-script");
3049                goto out_delete;
3050        }
3051
3052        if (script_name) {
3053                err = scripting_ops->start_script(script_name, argc, argv);
3054                if (err)
3055                        goto out_delete;
3056                pr_debug("perf script started with script %s\n\n", script_name);
3057                script_started = true;
3058        }
3059
3060
3061        err = perf_session__check_output_opt(session);
3062        if (err < 0)
3063                goto out_delete;
3064
3065        /* needs to be parsed after looking up reference time */
3066        if (perf_time__parse_str(&script.ptime, script.time_str) != 0) {
3067                pr_err("Invalid time string\n");
3068                return -EINVAL;
3069        }
3070
3071        err = __cmd_script(&script);
3072
3073        flush_scripting();
3074
3075out_delete:
3076        perf_evlist__free_stats(session->evlist);
3077        perf_session__delete(session);
3078
3079        if (script_started)
3080                cleanup_scripting();
3081out:
3082        return err;
3083}
3084