perf script: Add support for dumping symbols
[linux-2.6.git] / tools / perf / builtin-script.c
1 #include "builtin.h"
2
3 #include "perf.h"
4 #include "util/cache.h"
5 #include "util/debug.h"
6 #include "util/exec_cmd.h"
7 #include "util/header.h"
8 #include "util/parse-options.h"
9 #include "util/session.h"
10 #include "util/symbol.h"
11 #include "util/thread.h"
12 #include "util/trace-event.h"
13 #include "util/parse-options.h"
14 #include "util/util.h"
15
16 static char const               *script_name;
17 static char const               *generate_script_lang;
18 static bool                     debug_mode;
19 static u64                      last_timestamp;
20 static u64                      nr_unordered;
21 extern const struct option      record_options[];
22 static bool                     no_callchain;
23
24 enum perf_output_field {
25         PERF_OUTPUT_COMM            = 1U << 0,
26         PERF_OUTPUT_TID             = 1U << 1,
27         PERF_OUTPUT_PID             = 1U << 2,
28         PERF_OUTPUT_TIME            = 1U << 3,
29         PERF_OUTPUT_CPU             = 1U << 4,
30         PERF_OUTPUT_EVNAME          = 1U << 5,
31         PERF_OUTPUT_TRACE           = 1U << 6,
32         PERF_OUTPUT_SYM             = 1U << 7,
33 };
34
35 struct output_option {
36         const char *str;
37         enum perf_output_field field;
38 } all_output_options[] = {
39         {.str = "comm",  .field = PERF_OUTPUT_COMM},
40         {.str = "tid",   .field = PERF_OUTPUT_TID},
41         {.str = "pid",   .field = PERF_OUTPUT_PID},
42         {.str = "time",  .field = PERF_OUTPUT_TIME},
43         {.str = "cpu",   .field = PERF_OUTPUT_CPU},
44         {.str = "event", .field = PERF_OUTPUT_EVNAME},
45         {.str = "trace", .field = PERF_OUTPUT_TRACE},
46         {.str = "sym",   .field = PERF_OUTPUT_SYM},
47 };
48
49 /* default set to maintain compatibility with current format */
50 static u64 output_fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | \
51                            PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | \
52                            PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE;
53
54 static bool output_set_by_user;
55
56 #define PRINT_FIELD(x)  (output_fields & PERF_OUTPUT_##x)
57
58 static void print_sample_start(struct perf_sample *sample,
59                                struct thread *thread)
60 {
61         int type;
62         struct event *event;
63         const char *evname = NULL;
64         unsigned long secs;
65         unsigned long usecs;
66         unsigned long long nsecs;
67
68         if (PRINT_FIELD(COMM)) {
69                 if (latency_format)
70                         printf("%8.8s ", thread->comm);
71                 else if (PRINT_FIELD(SYM) && symbol_conf.use_callchain)
72                         printf("%s ", thread->comm);
73                 else
74                         printf("%16s ", thread->comm);
75         }
76
77         if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
78                 printf("%5d/%-5d ", sample->pid, sample->tid);
79         else if (PRINT_FIELD(PID))
80                 printf("%5d ", sample->pid);
81         else if (PRINT_FIELD(TID))
82                 printf("%5d ", sample->tid);
83
84         if (PRINT_FIELD(CPU)) {
85                 if (latency_format)
86                         printf("%3d ", sample->cpu);
87                 else
88                         printf("[%03d] ", sample->cpu);
89         }
90
91         if (PRINT_FIELD(TIME)) {
92                 nsecs = sample->time;
93                 secs = nsecs / NSECS_PER_SEC;
94                 nsecs -= secs * NSECS_PER_SEC;
95                 usecs = nsecs / NSECS_PER_USEC;
96                 printf("%5lu.%06lu: ", secs, usecs);
97         }
98
99         if (PRINT_FIELD(EVNAME)) {
100                 type = trace_parse_common_type(sample->raw_data);
101                 event = trace_find_event(type);
102                 if (event)
103                         evname = event->name;
104
105                 printf("%s: ", evname ? evname : "(unknown)");
106         }
107 }
108
109 static void process_event(union perf_event *event __unused,
110                           struct perf_sample *sample,
111                           struct perf_session *session __unused,
112                           struct thread *thread)
113 {
114         print_sample_start(sample, thread);
115
116         if (PRINT_FIELD(TRACE))
117                 print_trace_event(sample->cpu, sample->raw_data,
118                                   sample->raw_size);
119
120         if (PRINT_FIELD(SYM)) {
121                 if (!symbol_conf.use_callchain)
122                         printf(" ");
123                 else
124                         printf("\n");
125                 perf_session__print_symbols(event, sample, session);
126         }
127
128         printf("\n");
129 }
130
131 static int default_start_script(const char *script __unused,
132                                 int argc __unused,
133                                 const char **argv __unused)
134 {
135         return 0;
136 }
137
138 static int default_stop_script(void)
139 {
140         return 0;
141 }
142
143 static int default_generate_script(const char *outfile __unused)
144 {
145         return 0;
146 }
147
148 static struct scripting_ops default_scripting_ops = {
149         .start_script           = default_start_script,
150         .stop_script            = default_stop_script,
151         .process_event          = process_event,
152         .generate_script        = default_generate_script,
153 };
154
155 static struct scripting_ops     *scripting_ops;
156
157 static void setup_scripting(void)
158 {
159         setup_perl_scripting();
160         setup_python_scripting();
161
162         scripting_ops = &default_scripting_ops;
163 }
164
165 static int cleanup_scripting(void)
166 {
167         pr_debug("\nperf script stopped\n");
168
169         return scripting_ops->stop_script();
170 }
171
172 static char const               *input_name = "perf.data";
173
174 static int process_sample_event(union perf_event *event,
175                                 struct perf_sample *sample,
176                                 struct perf_session *session)
177 {
178         struct thread *thread = perf_session__findnew(session, event->ip.pid);
179
180         if (thread == NULL) {
181                 pr_debug("problem processing %d event, skipping it.\n",
182                          event->header.type);
183                 return -1;
184         }
185
186         if (session->sample_type & PERF_SAMPLE_RAW) {
187                 if (debug_mode) {
188                         if (sample->time < last_timestamp) {
189                                 pr_err("Samples misordered, previous: %" PRIu64
190                                         " this: %" PRIu64 "\n", last_timestamp,
191                                         sample->time);
192                                 nr_unordered++;
193                         }
194                         last_timestamp = sample->time;
195                         return 0;
196                 }
197                 scripting_ops->process_event(event, sample, session, thread);
198         }
199
200         session->hists.stats.total_period += sample->period;
201         return 0;
202 }
203
204 static struct perf_event_ops event_ops = {
205         .sample          = process_sample_event,
206         .mmap            = perf_event__process_mmap,
207         .comm            = perf_event__process_comm,
208         .exit            = perf_event__process_task,
209         .fork            = perf_event__process_task,
210         .attr            = perf_event__process_attr,
211         .event_type      = perf_event__process_event_type,
212         .tracing_data    = perf_event__process_tracing_data,
213         .build_id        = perf_event__process_build_id,
214         .ordered_samples = true,
215         .ordering_requires_timestamps = true,
216 };
217
218 extern volatile int session_done;
219
220 static void sig_handler(int sig __unused)
221 {
222         session_done = 1;
223 }
224
225 static int __cmd_script(struct perf_session *session)
226 {
227         int ret;
228
229         signal(SIGINT, sig_handler);
230
231         ret = perf_session__process_events(session, &event_ops);
232
233         if (debug_mode)
234                 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
235
236         return ret;
237 }
238
239 struct script_spec {
240         struct list_head        node;
241         struct scripting_ops    *ops;
242         char                    spec[0];
243 };
244
245 static LIST_HEAD(script_specs);
246
247 static struct script_spec *script_spec__new(const char *spec,
248                                             struct scripting_ops *ops)
249 {
250         struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
251
252         if (s != NULL) {
253                 strcpy(s->spec, spec);
254                 s->ops = ops;
255         }
256
257         return s;
258 }
259
260 static void script_spec__delete(struct script_spec *s)
261 {
262         free(s->spec);
263         free(s);
264 }
265
266 static void script_spec__add(struct script_spec *s)
267 {
268         list_add_tail(&s->node, &script_specs);
269 }
270
271 static struct script_spec *script_spec__find(const char *spec)
272 {
273         struct script_spec *s;
274
275         list_for_each_entry(s, &script_specs, node)
276                 if (strcasecmp(s->spec, spec) == 0)
277                         return s;
278         return NULL;
279 }
280
281 static struct script_spec *script_spec__findnew(const char *spec,
282                                                 struct scripting_ops *ops)
283 {
284         struct script_spec *s = script_spec__find(spec);
285
286         if (s)
287                 return s;
288
289         s = script_spec__new(spec, ops);
290         if (!s)
291                 goto out_delete_spec;
292
293         script_spec__add(s);
294
295         return s;
296
297 out_delete_spec:
298         script_spec__delete(s);
299
300         return NULL;
301 }
302
303 int script_spec_register(const char *spec, struct scripting_ops *ops)
304 {
305         struct script_spec *s;
306
307         s = script_spec__find(spec);
308         if (s)
309                 return -1;
310
311         s = script_spec__findnew(spec, ops);
312         if (!s)
313                 return -1;
314
315         return 0;
316 }
317
318 static struct scripting_ops *script_spec__lookup(const char *spec)
319 {
320         struct script_spec *s = script_spec__find(spec);
321         if (!s)
322                 return NULL;
323
324         return s->ops;
325 }
326
327 static void list_available_languages(void)
328 {
329         struct script_spec *s;
330
331         fprintf(stderr, "\n");
332         fprintf(stderr, "Scripting language extensions (used in "
333                 "perf script -s [spec:]script.[spec]):\n\n");
334
335         list_for_each_entry(s, &script_specs, node)
336                 fprintf(stderr, "  %-42s [%s]\n", s->spec, s->ops->name);
337
338         fprintf(stderr, "\n");
339 }
340
341 static int parse_scriptname(const struct option *opt __used,
342                             const char *str, int unset __used)
343 {
344         char spec[PATH_MAX];
345         const char *script, *ext;
346         int len;
347
348         if (strcmp(str, "lang") == 0) {
349                 list_available_languages();
350                 exit(0);
351         }
352
353         script = strchr(str, ':');
354         if (script) {
355                 len = script - str;
356                 if (len >= PATH_MAX) {
357                         fprintf(stderr, "invalid language specifier");
358                         return -1;
359                 }
360                 strncpy(spec, str, len);
361                 spec[len] = '\0';
362                 scripting_ops = script_spec__lookup(spec);
363                 if (!scripting_ops) {
364                         fprintf(stderr, "invalid language specifier");
365                         return -1;
366                 }
367                 script++;
368         } else {
369                 script = str;
370                 ext = strrchr(script, '.');
371                 if (!ext) {
372                         fprintf(stderr, "invalid script extension");
373                         return -1;
374                 }
375                 scripting_ops = script_spec__lookup(++ext);
376                 if (!scripting_ops) {
377                         fprintf(stderr, "invalid script extension");
378                         return -1;
379                 }
380         }
381
382         script_name = strdup(script);
383
384         return 0;
385 }
386
387 static int parse_output_fields(const struct option *opt __used,
388                             const char *arg, int unset __used)
389 {
390         char *tok;
391         int i, imax = sizeof(all_output_options) / sizeof(struct output_option);
392         int rc = 0;
393         char *str = strdup(arg);
394
395         if (!str)
396                 return -ENOMEM;
397
398         tok = strtok(str, ",");
399         if (!tok) {
400                 fprintf(stderr, "Invalid field string.");
401                 return -EINVAL;
402         }
403
404         output_fields = 0;
405         while (1) {
406                 for (i = 0; i < imax; ++i) {
407                         if (strcmp(tok, all_output_options[i].str) == 0) {
408                                 output_fields |= all_output_options[i].field;
409                                 break;
410                         }
411                 }
412                 if (i == imax) {
413                         fprintf(stderr, "Invalid field requested.");
414                         rc = -EINVAL;
415                         break;
416                 }
417
418                 tok = strtok(NULL, ",");
419                 if (!tok)
420                         break;
421         }
422
423         output_set_by_user = true;
424
425         free(str);
426         return rc;
427 }
428
429 /* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */
430 static int is_directory(const char *base_path, const struct dirent *dent)
431 {
432         char path[PATH_MAX];
433         struct stat st;
434
435         sprintf(path, "%s/%s", base_path, dent->d_name);
436         if (stat(path, &st))
437                 return 0;
438
439         return S_ISDIR(st.st_mode);
440 }
441
442 #define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\
443         while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) &&     \
444                lang_next)                                               \
445                 if ((lang_dirent.d_type == DT_DIR ||                    \
446                      (lang_dirent.d_type == DT_UNKNOWN &&               \
447                       is_directory(scripts_path, &lang_dirent))) &&     \
448                     (strcmp(lang_dirent.d_name, ".")) &&                \
449                     (strcmp(lang_dirent.d_name, "..")))
450
451 #define for_each_script(lang_path, lang_dir, script_dirent, script_next)\
452         while (!readdir_r(lang_dir, &script_dirent, &script_next) &&    \
453                script_next)                                             \
454                 if (script_dirent.d_type != DT_DIR &&                   \
455                     (script_dirent.d_type != DT_UNKNOWN ||              \
456                      !is_directory(lang_path, &script_dirent)))
457
458
459 #define RECORD_SUFFIX                   "-record"
460 #define REPORT_SUFFIX                   "-report"
461
462 struct script_desc {
463         struct list_head        node;
464         char                    *name;
465         char                    *half_liner;
466         char                    *args;
467 };
468
469 static LIST_HEAD(script_descs);
470
471 static struct script_desc *script_desc__new(const char *name)
472 {
473         struct script_desc *s = zalloc(sizeof(*s));
474
475         if (s != NULL && name)
476                 s->name = strdup(name);
477
478         return s;
479 }
480
481 static void script_desc__delete(struct script_desc *s)
482 {
483         free(s->name);
484         free(s->half_liner);
485         free(s->args);
486         free(s);
487 }
488
489 static void script_desc__add(struct script_desc *s)
490 {
491         list_add_tail(&s->node, &script_descs);
492 }
493
494 static struct script_desc *script_desc__find(const char *name)
495 {
496         struct script_desc *s;
497
498         list_for_each_entry(s, &script_descs, node)
499                 if (strcasecmp(s->name, name) == 0)
500                         return s;
501         return NULL;
502 }
503
504 static struct script_desc *script_desc__findnew(const char *name)
505 {
506         struct script_desc *s = script_desc__find(name);
507
508         if (s)
509                 return s;
510
511         s = script_desc__new(name);
512         if (!s)
513                 goto out_delete_desc;
514
515         script_desc__add(s);
516
517         return s;
518
519 out_delete_desc:
520         script_desc__delete(s);
521
522         return NULL;
523 }
524
525 static const char *ends_with(const char *str, const char *suffix)
526 {
527         size_t suffix_len = strlen(suffix);
528         const char *p = str;
529
530         if (strlen(str) > suffix_len) {
531                 p = str + strlen(str) - suffix_len;
532                 if (!strncmp(p, suffix, suffix_len))
533                         return p;
534         }
535
536         return NULL;
537 }
538
539 static char *ltrim(char *str)
540 {
541         int len = strlen(str);
542
543         while (len && isspace(*str)) {
544                 len--;
545                 str++;
546         }
547
548         return str;
549 }
550
551 static int read_script_info(struct script_desc *desc, const char *filename)
552 {
553         char line[BUFSIZ], *p;
554         FILE *fp;
555
556         fp = fopen(filename, "r");
557         if (!fp)
558                 return -1;
559
560         while (fgets(line, sizeof(line), fp)) {
561                 p = ltrim(line);
562                 if (strlen(p) == 0)
563                         continue;
564                 if (*p != '#')
565                         continue;
566                 p++;
567                 if (strlen(p) && *p == '!')
568                         continue;
569
570                 p = ltrim(p);
571                 if (strlen(p) && p[strlen(p) - 1] == '\n')
572                         p[strlen(p) - 1] = '\0';
573
574                 if (!strncmp(p, "description:", strlen("description:"))) {
575                         p += strlen("description:");
576                         desc->half_liner = strdup(ltrim(p));
577                         continue;
578                 }
579
580                 if (!strncmp(p, "args:", strlen("args:"))) {
581                         p += strlen("args:");
582                         desc->args = strdup(ltrim(p));
583                         continue;
584                 }
585         }
586
587         fclose(fp);
588
589         return 0;
590 }
591
592 static int list_available_scripts(const struct option *opt __used,
593                                   const char *s __used, int unset __used)
594 {
595         struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
596         char scripts_path[MAXPATHLEN];
597         DIR *scripts_dir, *lang_dir;
598         char script_path[MAXPATHLEN];
599         char lang_path[MAXPATHLEN];
600         struct script_desc *desc;
601         char first_half[BUFSIZ];
602         char *script_root;
603         char *str;
604
605         snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
606
607         scripts_dir = opendir(scripts_path);
608         if (!scripts_dir)
609                 return -1;
610
611         for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
612                 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
613                          lang_dirent.d_name);
614                 lang_dir = opendir(lang_path);
615                 if (!lang_dir)
616                         continue;
617
618                 for_each_script(lang_path, lang_dir, script_dirent, script_next) {
619                         script_root = strdup(script_dirent.d_name);
620                         str = (char *)ends_with(script_root, REPORT_SUFFIX);
621                         if (str) {
622                                 *str = '\0';
623                                 desc = script_desc__findnew(script_root);
624                                 snprintf(script_path, MAXPATHLEN, "%s/%s",
625                                          lang_path, script_dirent.d_name);
626                                 read_script_info(desc, script_path);
627                         }
628                         free(script_root);
629                 }
630         }
631
632         fprintf(stdout, "List of available trace scripts:\n");
633         list_for_each_entry(desc, &script_descs, node) {
634                 sprintf(first_half, "%s %s", desc->name,
635                         desc->args ? desc->args : "");
636                 fprintf(stdout, "  %-36s %s\n", first_half,
637                         desc->half_liner ? desc->half_liner : "");
638         }
639
640         exit(0);
641 }
642
643 static char *get_script_path(const char *script_root, const char *suffix)
644 {
645         struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
646         char scripts_path[MAXPATHLEN];
647         char script_path[MAXPATHLEN];
648         DIR *scripts_dir, *lang_dir;
649         char lang_path[MAXPATHLEN];
650         char *str, *__script_root;
651         char *path = NULL;
652
653         snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
654
655         scripts_dir = opendir(scripts_path);
656         if (!scripts_dir)
657                 return NULL;
658
659         for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
660                 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
661                          lang_dirent.d_name);
662                 lang_dir = opendir(lang_path);
663                 if (!lang_dir)
664                         continue;
665
666                 for_each_script(lang_path, lang_dir, script_dirent, script_next) {
667                         __script_root = strdup(script_dirent.d_name);
668                         str = (char *)ends_with(__script_root, suffix);
669                         if (str) {
670                                 *str = '\0';
671                                 if (strcmp(__script_root, script_root))
672                                         continue;
673                                 snprintf(script_path, MAXPATHLEN, "%s/%s",
674                                          lang_path, script_dirent.d_name);
675                                 path = strdup(script_path);
676                                 free(__script_root);
677                                 break;
678                         }
679                         free(__script_root);
680                 }
681         }
682
683         return path;
684 }
685
686 static bool is_top_script(const char *script_path)
687 {
688         return ends_with(script_path, "top") == NULL ? false : true;
689 }
690
691 static int has_required_arg(char *script_path)
692 {
693         struct script_desc *desc;
694         int n_args = 0;
695         char *p;
696
697         desc = script_desc__new(NULL);
698
699         if (read_script_info(desc, script_path))
700                 goto out;
701
702         if (!desc->args)
703                 goto out;
704
705         for (p = desc->args; *p; p++)
706                 if (*p == '<')
707                         n_args++;
708 out:
709         script_desc__delete(desc);
710
711         return n_args;
712 }
713
714 static const char * const script_usage[] = {
715         "perf script [<options>]",
716         "perf script [<options>] record <script> [<record-options>] <command>",
717         "perf script [<options>] report <script> [script-args]",
718         "perf script [<options>] <script> [<record-options>] <command>",
719         "perf script [<options>] <top-script> [script-args]",
720         NULL
721 };
722
723 static const struct option options[] = {
724         OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
725                     "dump raw trace in ASCII"),
726         OPT_INCR('v', "verbose", &verbose,
727                     "be more verbose (show symbol address, etc)"),
728         OPT_BOOLEAN('L', "Latency", &latency_format,
729                     "show latency attributes (irqs/preemption disabled, etc)"),
730         OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
731                            list_available_scripts),
732         OPT_CALLBACK('s', "script", NULL, "name",
733                      "script file name (lang:script name, script name, or *)",
734                      parse_scriptname),
735         OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
736                    "generate perf-script.xx script in specified language"),
737         OPT_STRING('i', "input", &input_name, "file",
738                     "input file name"),
739         OPT_BOOLEAN('d', "debug-mode", &debug_mode,
740                    "do various checks like samples ordering and lost events"),
741         OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
742                    "file", "vmlinux pathname"),
743         OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
744                    "file", "kallsyms pathname"),
745         OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
746                     "When printing symbols do not display call chain"),
747         OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
748                     "Look for files with symbols relative to this directory"),
749         OPT_CALLBACK('f', "fields", NULL, "str",
750                      "comma separated output fields. Options: comm,tid,pid,time,cpu,event,trace,sym",
751                      parse_output_fields),
752
753         OPT_END()
754 };
755
756 static bool have_cmd(int argc, const char **argv)
757 {
758         char **__argv = malloc(sizeof(const char *) * argc);
759
760         if (!__argv)
761                 die("malloc");
762         memcpy(__argv, argv, sizeof(const char *) * argc);
763         argc = parse_options(argc, (const char **)__argv, record_options,
764                              NULL, PARSE_OPT_STOP_AT_NON_OPTION);
765         free(__argv);
766
767         return argc != 0;
768 }
769
770 int cmd_script(int argc, const char **argv, const char *prefix __used)
771 {
772         char *rec_script_path = NULL;
773         char *rep_script_path = NULL;
774         struct perf_session *session;
775         char *script_path = NULL;
776         const char **__argv;
777         bool system_wide;
778         int i, j, err;
779
780         setup_scripting();
781
782         argc = parse_options(argc, argv, options, script_usage,
783                              PARSE_OPT_STOP_AT_NON_OPTION);
784
785         if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
786                 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
787                 if (!rec_script_path)
788                         return cmd_record(argc, argv, NULL);
789         }
790
791         if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
792                 rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
793                 if (!rep_script_path) {
794                         fprintf(stderr,
795                                 "Please specify a valid report script"
796                                 "(see 'perf script -l' for listing)\n");
797                         return -1;
798                 }
799         }
800
801         /* make sure PERF_EXEC_PATH is set for scripts */
802         perf_set_argv_exec_path(perf_exec_path());
803
804         if (argc && !script_name && !rec_script_path && !rep_script_path) {
805                 int live_pipe[2];
806                 int rep_args;
807                 pid_t pid;
808
809                 rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);
810                 rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
811
812                 if (!rec_script_path && !rep_script_path) {
813                         fprintf(stderr, " Couldn't find script %s\n\n See perf"
814                                 " script -l for available scripts.\n", argv[0]);
815                         usage_with_options(script_usage, options);
816                 }
817
818                 if (is_top_script(argv[0])) {
819                         rep_args = argc - 1;
820                 } else {
821                         int rec_args;
822
823                         rep_args = has_required_arg(rep_script_path);
824                         rec_args = (argc - 1) - rep_args;
825                         if (rec_args < 0) {
826                                 fprintf(stderr, " %s script requires options."
827                                         "\n\n See perf script -l for available "
828                                         "scripts and options.\n", argv[0]);
829                                 usage_with_options(script_usage, options);
830                         }
831                 }
832
833                 if (pipe(live_pipe) < 0) {
834                         perror("failed to create pipe");
835                         exit(-1);
836                 }
837
838                 pid = fork();
839                 if (pid < 0) {
840                         perror("failed to fork");
841                         exit(-1);
842                 }
843
844                 if (!pid) {
845                         system_wide = true;
846                         j = 0;
847
848                         dup2(live_pipe[1], 1);
849                         close(live_pipe[0]);
850
851                         if (!is_top_script(argv[0]))
852                                 system_wide = !have_cmd(argc - rep_args,
853                                                         &argv[rep_args]);
854
855                         __argv = malloc((argc + 6) * sizeof(const char *));
856                         if (!__argv)
857                                 die("malloc");
858
859                         __argv[j++] = "/bin/sh";
860                         __argv[j++] = rec_script_path;
861                         if (system_wide)
862                                 __argv[j++] = "-a";
863                         __argv[j++] = "-q";
864                         __argv[j++] = "-o";
865                         __argv[j++] = "-";
866                         for (i = rep_args + 1; i < argc; i++)
867                                 __argv[j++] = argv[i];
868                         __argv[j++] = NULL;
869
870                         execvp("/bin/sh", (char **)__argv);
871                         free(__argv);
872                         exit(-1);
873                 }
874
875                 dup2(live_pipe[0], 0);
876                 close(live_pipe[1]);
877
878                 __argv = malloc((argc + 4) * sizeof(const char *));
879                 if (!__argv)
880                         die("malloc");
881                 j = 0;
882                 __argv[j++] = "/bin/sh";
883                 __argv[j++] = rep_script_path;
884                 for (i = 1; i < rep_args + 1; i++)
885                         __argv[j++] = argv[i];
886                 __argv[j++] = "-i";
887                 __argv[j++] = "-";
888                 __argv[j++] = NULL;
889
890                 execvp("/bin/sh", (char **)__argv);
891                 free(__argv);
892                 exit(-1);
893         }
894
895         if (rec_script_path)
896                 script_path = rec_script_path;
897         if (rep_script_path)
898                 script_path = rep_script_path;
899
900         if (script_path) {
901                 system_wide = false;
902                 j = 0;
903
904                 if (rec_script_path)
905                         system_wide = !have_cmd(argc - 1, &argv[1]);
906
907                 __argv = malloc((argc + 2) * sizeof(const char *));
908                 if (!__argv)
909                         die("malloc");
910                 __argv[j++] = "/bin/sh";
911                 __argv[j++] = script_path;
912                 if (system_wide)
913                         __argv[j++] = "-a";
914                 for (i = 2; i < argc; i++)
915                         __argv[j++] = argv[i];
916                 __argv[j++] = NULL;
917
918                 execvp("/bin/sh", (char **)__argv);
919                 free(__argv);
920                 exit(-1);
921         }
922
923         if (symbol__init() < 0)
924                 return -1;
925         if (!script_name)
926                 setup_pager();
927
928         session = perf_session__new(input_name, O_RDONLY, 0, false, &event_ops);
929         if (session == NULL)
930                 return -ENOMEM;
931
932         if (!no_callchain && (session->sample_type & PERF_SAMPLE_CALLCHAIN))
933                 symbol_conf.use_callchain = true;
934         else
935                 symbol_conf.use_callchain = false;
936
937         if (strcmp(input_name, "-") &&
938             !perf_session__has_traces(session, "record -R"))
939                 return -EINVAL;
940
941         if (generate_script_lang) {
942                 struct stat perf_stat;
943                 int input;
944
945                 if (output_set_by_user) {
946                         fprintf(stderr,
947                                 "custom fields not supported for generated scripts");
948                         return -1;
949                 }
950
951                 input = open(input_name, O_RDONLY);
952                 if (input < 0) {
953                         perror("failed to open file");
954                         exit(-1);
955                 }
956
957                 err = fstat(input, &perf_stat);
958                 if (err < 0) {
959                         perror("failed to stat file");
960                         exit(-1);
961                 }
962
963                 if (!perf_stat.st_size) {
964                         fprintf(stderr, "zero-sized file, nothing to do!\n");
965                         exit(0);
966                 }
967
968                 scripting_ops = script_spec__lookup(generate_script_lang);
969                 if (!scripting_ops) {
970                         fprintf(stderr, "invalid language specifier");
971                         return -1;
972                 }
973
974                 err = scripting_ops->generate_script("perf-script");
975                 goto out;
976         }
977
978         if (script_name) {
979                 err = scripting_ops->start_script(script_name, argc, argv);
980                 if (err)
981                         goto out;
982                 pr_debug("perf script started with script %s\n\n", script_name);
983         }
984
985         err = __cmd_script(session);
986
987         perf_session__delete(session);
988         cleanup_scripting();
989 out:
990         return err;
991 }