These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / tools / perf / builtin-script.c
index 58f10b8..72b5deb 100644 (file)
@@ -6,6 +6,7 @@
 #include "util/exec_cmd.h"
 #include "util/header.h"
 #include "util/parse-options.h"
+#include "util/perf_regs.h"
 #include "util/session.h"
 #include "util/tool.h"
 #include "util/symbol.h"
@@ -16,6 +17,7 @@
 #include "util/evsel.h"
 #include "util/sort.h"
 #include "util/data.h"
+#include "util/auxtrace.h"
 #include <linux/bitmap.h>
 
 static char const              *script_name;
@@ -26,9 +28,13 @@ static u64                   nr_unordered;
 static bool                    no_callchain;
 static bool                    latency_format;
 static bool                    system_wide;
+static bool                    print_flags;
+static bool                    nanosecs;
 static const char              *cpu_list;
 static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
 
+unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
+
 enum perf_output_field {
        PERF_OUTPUT_COMM            = 1U << 0,
        PERF_OUTPUT_TID             = 1U << 1,
@@ -44,6 +50,9 @@ enum perf_output_field {
        PERF_OUTPUT_SYMOFFSET       = 1U << 11,
        PERF_OUTPUT_SRCLINE         = 1U << 12,
        PERF_OUTPUT_PERIOD          = 1U << 13,
+       PERF_OUTPUT_IREGS           = 1U << 14,
+       PERF_OUTPUT_BRSTACK         = 1U << 15,
+       PERF_OUTPUT_BRSTACKSYM      = 1U << 16,
 };
 
 struct output_option {
@@ -64,6 +73,9 @@ struct output_option {
        {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
        {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
        {.str = "period", .field = PERF_OUTPUT_PERIOD},
+       {.str = "iregs", .field = PERF_OUTPUT_IREGS},
+       {.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
+       {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
 };
 
 /* default set to maintain compatibility with current format */
@@ -146,9 +158,10 @@ static const char *output_field2str(enum perf_output_field field)
 
 #define PRINT_FIELD(x)  (output[attr->type].fields & PERF_OUTPUT_##x)
 
-static int perf_evsel__check_stype(struct perf_evsel *evsel,
-                                  u64 sample_type, const char *sample_msg,
-                                  enum perf_output_field field)
+static int perf_evsel__do_check_stype(struct perf_evsel *evsel,
+                                     u64 sample_type, const char *sample_msg,
+                                     enum perf_output_field field,
+                                     bool allow_user_set)
 {
        struct perf_event_attr *attr = &evsel->attr;
        int type = attr->type;
@@ -158,6 +171,8 @@ static int perf_evsel__check_stype(struct perf_evsel *evsel,
                return 0;
 
        if (output[type].user_set) {
+               if (allow_user_set)
+                       return 0;
                evname = perf_evsel__name(evsel);
                pr_err("Samples for '%s' event do not have %s attribute set. "
                       "Cannot print '%s' field.\n",
@@ -175,10 +190,22 @@ static int perf_evsel__check_stype(struct perf_evsel *evsel,
        return 0;
 }
 
+static int perf_evsel__check_stype(struct perf_evsel *evsel,
+                                  u64 sample_type, const char *sample_msg,
+                                  enum perf_output_field field)
+{
+       return perf_evsel__do_check_stype(evsel, sample_type, sample_msg, field,
+                                         false);
+}
+
 static int perf_evsel__check_attr(struct perf_evsel *evsel,
                                  struct perf_session *session)
 {
        struct perf_event_attr *attr = &evsel->attr;
+       bool allow_user_set;
+
+       allow_user_set = perf_header__has_feat(&session->header,
+                                              HEADER_AUXTRACE);
 
        if (PRINT_FIELD(TRACE) &&
                !perf_session__has_traces(session, "record -R"))
@@ -191,8 +218,8 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
        }
 
        if (PRINT_FIELD(ADDR) &&
-               perf_evsel__check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR",
-                                       PERF_OUTPUT_ADDR))
+               perf_evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR",
+                                          PERF_OUTPUT_ADDR, allow_user_set))
                return -EINVAL;
 
        if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
@@ -229,8 +256,8 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
                return -EINVAL;
 
        if (PRINT_FIELD(CPU) &&
-               perf_evsel__check_stype(evsel, PERF_SAMPLE_CPU, "CPU",
-                                       PERF_OUTPUT_CPU))
+               perf_evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU",
+                                          PERF_OUTPUT_CPU, allow_user_set))
                return -EINVAL;
 
        if (PRINT_FIELD(PERIOD) &&
@@ -238,6 +265,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
                                        PERF_OUTPUT_PERIOD))
                return -EINVAL;
 
+       if (PRINT_FIELD(IREGS) &&
+               perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS",
+                                       PERF_OUTPUT_IREGS))
+               return -EINVAL;
+
        return 0;
 }
 
@@ -335,6 +367,24 @@ out:
        return 0;
 }
 
+static void print_sample_iregs(union perf_event *event __maybe_unused,
+                         struct perf_sample *sample,
+                         struct thread *thread __maybe_unused,
+                         struct perf_event_attr *attr)
+{
+       struct regs_dump *regs = &sample->intr_regs;
+       uint64_t mask = attr->sample_regs_intr;
+       unsigned i = 0, r;
+
+       if (!regs)
+               return;
+
+       for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
+               u64 val = regs->regs[i++];
+               printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
+       }
+}
+
 static void print_sample_start(struct perf_sample *sample,
                               struct thread *thread,
                               struct perf_evsel *evsel)
@@ -372,10 +422,84 @@ static void print_sample_start(struct perf_sample *sample,
                secs = nsecs / NSECS_PER_SEC;
                nsecs -= secs * NSECS_PER_SEC;
                usecs = nsecs / NSECS_PER_USEC;
-               printf("%5lu.%06lu: ", secs, usecs);
+               if (nanosecs)
+                       printf("%5lu.%09llu: ", secs, nsecs);
+               else
+                       printf("%5lu.%06lu: ", secs, usecs);
+       }
+}
+
+static inline char
+mispred_str(struct branch_entry *br)
+{
+       if (!(br->flags.mispred  || br->flags.predicted))
+               return '-';
+
+       return br->flags.predicted ? 'P' : 'M';
+}
+
+static void print_sample_brstack(union perf_event *event __maybe_unused,
+                         struct perf_sample *sample,
+                         struct thread *thread __maybe_unused,
+                         struct perf_event_attr *attr __maybe_unused)
+{
+       struct branch_stack *br = sample->branch_stack;
+       u64 i;
+
+       if (!(br && br->nr))
+               return;
+
+       for (i = 0; i < br->nr; i++) {
+               printf(" 0x%"PRIx64"/0x%"PRIx64"/%c/%c/%c/%d ",
+                       br->entries[i].from,
+                       br->entries[i].to,
+                       mispred_str( br->entries + i),
+                       br->entries[i].flags.in_tx? 'X' : '-',
+                       br->entries[i].flags.abort? 'A' : '-',
+                       br->entries[i].flags.cycles);
        }
 }
 
+static void print_sample_brstacksym(union perf_event *event __maybe_unused,
+                         struct perf_sample *sample,
+                         struct thread *thread __maybe_unused,
+                         struct perf_event_attr *attr __maybe_unused)
+{
+       struct branch_stack *br = sample->branch_stack;
+       struct addr_location alf, alt;
+       u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+       u64 i, from, to;
+
+       if (!(br && br->nr))
+               return;
+
+       for (i = 0; i < br->nr; i++) {
+
+               memset(&alf, 0, sizeof(alf));
+               memset(&alt, 0, sizeof(alt));
+               from = br->entries[i].from;
+               to   = br->entries[i].to;
+
+               thread__find_addr_map(thread, cpumode, MAP__FUNCTION, from, &alf);
+               if (alf.map)
+                       alf.sym = map__find_symbol(alf.map, alf.addr, NULL);
+
+               thread__find_addr_map(thread, cpumode, MAP__FUNCTION, to, &alt);
+               if (alt.map)
+                       alt.sym = map__find_symbol(alt.map, alt.addr, NULL);
+
+               symbol__fprintf_symname_offs(alf.sym, &alf, stdout);
+               putchar('/');
+               symbol__fprintf_symname_offs(alt.sym, &alt, stdout);
+               printf("/%c/%c/%c/%d ",
+                       mispred_str( br->entries + i),
+                       br->entries[i].flags.in_tx? 'X' : '-',
+                       br->entries[i].flags.abort? 'A' : '-',
+                       br->entries[i].flags.cycles);
+       }
+}
+
+
 static void print_sample_addr(union perf_event *event,
                          struct perf_sample *sample,
                          struct thread *thread,
@@ -428,7 +552,7 @@ static void print_sample_bts(union perf_event *event,
                        }
                }
                perf_evsel__print_ip(evsel, sample, al, print_opts,
-                                    PERF_MAX_STACK_DEPTH);
+                                    scripting_max_stack);
        }
 
        /* print branch_to information */
@@ -445,6 +569,25 @@ static void print_sample_bts(union perf_event *event,
        printf("\n");
 }
 
+static void print_sample_flags(u32 flags)
+{
+       const char *chars = PERF_IP_FLAG_CHARS;
+       const int n = strlen(PERF_IP_FLAG_CHARS);
+       char str[33];
+       int i, pos = 0;
+
+       for (i = 0; i < n; i++, flags >>= 1) {
+               if (flags & 1)
+                       str[pos++] = chars[i];
+       }
+       for (; i < 32; i++, flags >>= 1) {
+               if (flags & 1)
+                       str[pos++] = '?';
+       }
+       str[pos] = 0;
+       printf("  %-4s ", str);
+}
+
 static void process_event(union perf_event *event, struct perf_sample *sample,
                          struct perf_evsel *evsel, struct addr_location *al)
 {
@@ -464,6 +607,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
                printf("%s: ", evname ? evname : "[unknown]");
        }
 
+       if (print_flags)
+               print_sample_flags(sample->flags);
+
        if (is_bts_event(attr)) {
                print_sample_bts(event, sample, evsel, thread, al);
                return;
@@ -483,9 +629,17 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
 
                perf_evsel__print_ip(evsel, sample, al,
                                     output[attr->type].print_ip_opts,
-                                    PERF_MAX_STACK_DEPTH);
+                                    scripting_max_stack);
        }
 
+       if (PRINT_FIELD(IREGS))
+               print_sample_iregs(event, sample, thread, attr);
+
+       if (PRINT_FIELD(BRSTACK))
+               print_sample_brstack(event, sample, thread, attr);
+       else if (PRINT_FIELD(BRSTACKSYM))
+               print_sample_brstacksym(event, sample, thread, attr);
+
        printf("\n");
 }
 
@@ -568,13 +722,14 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
        }
 
        if (al.filtered)
-               return 0;
+               goto out_put;
 
        if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
-               return 0;
+               goto out_put;
 
        scripting_ops->process_event(event, sample, evsel, &al);
-
+out_put:
+       addr_location__put(&al);
        return 0;
 }
 
@@ -583,6 +738,7 @@ struct perf_script {
        struct perf_session     *session;
        bool                    show_task_events;
        bool                    show_mmap_events;
+       bool                    show_switch_events;
 };
 
 static int process_attr(struct perf_tool *tool, union perf_event *event,
@@ -610,7 +766,10 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
 
        set_print_ip_opts(&evsel->attr);
 
-       return perf_evsel__check_attr(evsel, scr->session);
+       if (evsel->attr.sample_type)
+               err = perf_evsel__check_attr(evsel, scr->session);
+
+       return err;
 }
 
 static int process_comm_event(struct perf_tool *tool,
@@ -621,7 +780,7 @@ static int process_comm_event(struct perf_tool *tool,
        struct thread *thread;
        struct perf_script *script = container_of(tool, struct perf_script, tool);
        struct perf_session *session = script->session;
-       struct perf_evsel *evsel = perf_evlist__first(session->evlist);
+       struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
        int ret = -1;
 
        thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid);
@@ -642,8 +801,8 @@ static int process_comm_event(struct perf_tool *tool,
        print_sample_start(sample, thread, evsel);
        perf_event__fprintf(event, stdout);
        ret = 0;
-
 out:
+       thread__put(thread);
        return ret;
 }
 
@@ -655,7 +814,7 @@ static int process_fork_event(struct perf_tool *tool,
        struct thread *thread;
        struct perf_script *script = container_of(tool, struct perf_script, tool);
        struct perf_session *session = script->session;
-       struct perf_evsel *evsel = perf_evlist__first(session->evlist);
+       struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
 
        if (perf_event__process_fork(tool, event, sample, machine) < 0)
                return -1;
@@ -674,6 +833,7 @@ static int process_fork_event(struct perf_tool *tool,
        }
        print_sample_start(sample, thread, evsel);
        perf_event__fprintf(event, stdout);
+       thread__put(thread);
 
        return 0;
 }
@@ -682,10 +842,11 @@ static int process_exit_event(struct perf_tool *tool,
                              struct perf_sample *sample,
                              struct machine *machine)
 {
+       int err = 0;
        struct thread *thread;
        struct perf_script *script = container_of(tool, struct perf_script, tool);
        struct perf_session *session = script->session;
-       struct perf_evsel *evsel = perf_evlist__first(session->evlist);
+       struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
 
        thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid);
        if (thread == NULL) {
@@ -696,16 +857,17 @@ static int process_exit_event(struct perf_tool *tool,
        if (!evsel->attr.sample_id_all) {
                sample->cpu = 0;
                sample->time = 0;
-               sample->tid = event->comm.tid;
-               sample->pid = event->comm.pid;
+               sample->tid = event->fork.tid;
+               sample->pid = event->fork.pid;
        }
        print_sample_start(sample, thread, evsel);
        perf_event__fprintf(event, stdout);
 
        if (perf_event__process_exit(tool, event, sample, machine) < 0)
-               return -1;
+               err = -1;
 
-       return 0;
+       thread__put(thread);
+       return err;
 }
 
 static int process_mmap_event(struct perf_tool *tool,
@@ -716,7 +878,7 @@ static int process_mmap_event(struct perf_tool *tool,
        struct thread *thread;
        struct perf_script *script = container_of(tool, struct perf_script, tool);
        struct perf_session *session = script->session;
-       struct perf_evsel *evsel = perf_evlist__first(session->evlist);
+       struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
 
        if (perf_event__process_mmap(tool, event, sample, machine) < 0)
                return -1;
@@ -735,7 +897,7 @@ static int process_mmap_event(struct perf_tool *tool,
        }
        print_sample_start(sample, thread, evsel);
        perf_event__fprintf(event, stdout);
-
+       thread__put(thread);
        return 0;
 }
 
@@ -747,7 +909,7 @@ static int process_mmap2_event(struct perf_tool *tool,
        struct thread *thread;
        struct perf_script *script = container_of(tool, struct perf_script, tool);
        struct perf_session *session = script->session;
-       struct perf_evsel *evsel = perf_evlist__first(session->evlist);
+       struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
 
        if (perf_event__process_mmap2(tool, event, sample, machine) < 0)
                return -1;
@@ -766,7 +928,33 @@ static int process_mmap2_event(struct perf_tool *tool,
        }
        print_sample_start(sample, thread, evsel);
        perf_event__fprintf(event, stdout);
+       thread__put(thread);
+       return 0;
+}
+
+static int process_switch_event(struct perf_tool *tool,
+                               union perf_event *event,
+                               struct perf_sample *sample,
+                               struct machine *machine)
+{
+       struct thread *thread;
+       struct perf_script *script = container_of(tool, struct perf_script, tool);
+       struct perf_session *session = script->session;
+       struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+
+       if (perf_event__process_switch(tool, event, sample, machine) < 0)
+               return -1;
 
+       thread = machine__findnew_thread(machine, sample->pid,
+                                        sample->tid);
+       if (thread == NULL) {
+               pr_debug("problem processing SWITCH event, skipping it.\n");
+               return -1;
+       }
+
+       print_sample_start(sample, thread, evsel);
+       perf_event__fprintf(event, stdout);
+       thread__put(thread);
        return 0;
 }
 
@@ -791,6 +979,8 @@ static int __cmd_script(struct perf_script *script)
                script->tool.mmap = process_mmap_event;
                script->tool.mmap2 = process_mmap2_event;
        }
+       if (script->show_switch_events)
+               script->tool.context_switch = process_switch_event;
 
        ret = perf_session__process_events(script->session);
 
@@ -999,12 +1189,15 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
                }
        }
 
-       tok = strtok(tok, ",");
-       while (tok) {
+       for (tok = strtok(tok, ","); tok; tok = strtok(NULL, ",")) {
                for (i = 0; i < imax; ++i) {
                        if (strcmp(tok, all_output_options[i].str) == 0)
                                break;
                }
+               if (i == imax && strcmp(tok, "flags") == 0) {
+                       print_flags = true;
+                       continue;
+               }
                if (i == imax) {
                        fprintf(stderr, "Invalid field requested.\n");
                        rc = -EINVAL;
@@ -1032,8 +1225,6 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
                        }
                        output[type].fields |= all_output_options[i].field;
                }
-
-               tok = strtok(NULL, ",");
        }
 
        if (type >= 0) {
@@ -1488,6 +1679,22 @@ static int have_cmd(int argc, const char **argv)
        return 0;
 }
 
+static void script__setup_sample_type(struct perf_script *script)
+{
+       struct perf_session *session = script->session;
+       u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
+
+       if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
+               if ((sample_type & PERF_SAMPLE_REGS_USER) &&
+                   (sample_type & PERF_SAMPLE_STACK_USER))
+                       callchain_param.record_mode = CALLCHAIN_DWARF;
+               else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
+                       callchain_param.record_mode = CALLCHAIN_LBR;
+               else
+                       callchain_param.record_mode = CALLCHAIN_FP;
+       }
+}
+
 int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 {
        bool show_full_info = false;
@@ -1497,6 +1704,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
        char *rec_script_path = NULL;
        char *rep_script_path = NULL;
        struct perf_session *session;
+       struct itrace_synth_opts itrace_synth_opts = { .set = false, };
        char *script_path = NULL;
        const char **__argv;
        int i, j, err = 0;
@@ -1511,6 +1719,10 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
                        .attr            = process_attr,
                        .tracing_data    = perf_event__process_tracing_data,
                        .build_id        = perf_event__process_build_id,
+                       .id_index        = perf_event__process_id_index,
+                       .auxtrace_info   = perf_event__process_auxtrace_info,
+                       .auxtrace        = perf_event__process_auxtrace,
+                       .auxtrace_error  = perf_event__process_auxtrace_error,
                        .ordered_events  = true,
                        .ordering_requires_timestamps = true,
                },
@@ -1549,7 +1761,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
                     "comma separated output fields prepend with 'type:'. "
                     "Valid types: hw,sw,trace,raw. "
                     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
-                    "addr,symoff,period", parse_output_fields),
+                    "addr,symoff,period,iregs,brstack,brstacksym,flags", parse_output_fields),
        OPT_BOOLEAN('a', "all-cpus", &system_wide,
                    "system-wide collection from all CPUs"),
        OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
@@ -1569,7 +1781,21 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
                    "Show the fork/comm/exit events"),
        OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
                    "Show the mmap events"),
+       OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
+                   "Show context switch events (if recorded)"),
        OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"),
+       OPT_BOOLEAN(0, "ns", &nanosecs,
+                   "Use 9 decimal places when displaying time"),
+       OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
+                           "Instruction Tracing options",
+                           itrace_parse_synth_opts),
+       OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
+                       "Show full source file name path for source lines"),
+       OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
+                       "Enable symbol demangling"),
+       OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
+                       "Enable kernel symbol demangling"),
+
        OPT_END()
        };
        const char * const script_subcommands[] = { "record", "report", NULL };
@@ -1605,6 +1831,10 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
                }
        }
 
+       if (itrace_synth_opts.callchain &&
+           itrace_synth_opts.callchain_sz > scripting_max_stack)
+               scripting_max_stack = itrace_synth_opts.callchain_sz;
+
        /* make sure PERF_EXEC_PATH is set for scripts */
        perf_set_argv_exec_path(perf_exec_path());
 
@@ -1617,9 +1847,9 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
                rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
 
                if (!rec_script_path && !rep_script_path) {
-                       fprintf(stderr, " Couldn't find script %s\n\n See perf"
+                       usage_with_options_msg(script_usage, options,
+                               "Couldn't find script `%s'\n\n See perf"
                                " script -l for available scripts.\n", argv[0]);
-                       usage_with_options(script_usage, options);
                }
 
                if (is_top_script(argv[0])) {
@@ -1630,10 +1860,10 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
                        rep_args = has_required_arg(rep_script_path);
                        rec_args = (argc - 1) - rep_args;
                        if (rec_args < 0) {
-                               fprintf(stderr, " %s script requires options."
+                               usage_with_options_msg(script_usage, options,
+                                       "`%s' script requires options."
                                        "\n\n See perf script -l for available "
                                        "scripts and options.\n", argv[0]);
-                               usage_with_options(script_usage, options);
                        }
                }
 
@@ -1764,6 +1994,9 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
                goto out_delete;
 
        script.session = session;
+       script__setup_sample_type(&script);
+
+       session->itrace_synth_opts = &itrace_synth_opts;
 
        if (cpu_list) {
                err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
@@ -1776,6 +2009,14 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
        else
                symbol_conf.use_callchain = false;
 
+       if (session->tevent.pevent &&
+           pevent_set_function_resolver(session->tevent.pevent,
+                                        machine__resolve_kernel_addr,
+                                        &session->machines.host) < 0) {
+               pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
+               return -1;
+       }
+
        if (generate_script_lang) {
                struct stat perf_stat;
                int input;