aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c739
1 files changed, 465 insertions, 274 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 83cdc0a61fd6..68f36dc0344f 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1#include "builtin.h" 2#include "builtin.h"
2 3
3#include "perf.h" 4#include "perf.h"
@@ -87,6 +88,8 @@ enum perf_output_field {
87 PERF_OUTPUT_BRSTACKINSN = 1U << 23, 88 PERF_OUTPUT_BRSTACKINSN = 1U << 23,
88 PERF_OUTPUT_BRSTACKOFF = 1U << 24, 89 PERF_OUTPUT_BRSTACKOFF = 1U << 24,
89 PERF_OUTPUT_SYNTH = 1U << 25, 90 PERF_OUTPUT_SYNTH = 1U << 25,
91 PERF_OUTPUT_PHYS_ADDR = 1U << 26,
92 PERF_OUTPUT_UREGS = 1U << 27,
90}; 93};
91 94
92struct output_option { 95struct output_option {
@@ -108,6 +111,7 @@ struct output_option {
108 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, 111 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
109 {.str = "period", .field = PERF_OUTPUT_PERIOD}, 112 {.str = "period", .field = PERF_OUTPUT_PERIOD},
110 {.str = "iregs", .field = PERF_OUTPUT_IREGS}, 113 {.str = "iregs", .field = PERF_OUTPUT_IREGS},
114 {.str = "uregs", .field = PERF_OUTPUT_UREGS},
111 {.str = "brstack", .field = PERF_OUTPUT_BRSTACK}, 115 {.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
112 {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM}, 116 {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
113 {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC}, 117 {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},
@@ -119,6 +123,7 @@ struct output_option {
119 {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN}, 123 {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
120 {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF}, 124 {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
121 {.str = "synth", .field = PERF_OUTPUT_SYNTH}, 125 {.str = "synth", .field = PERF_OUTPUT_SYNTH},
126 {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
122}; 127};
123 128
124enum { 129enum {
@@ -175,7 +180,8 @@ static struct {
175 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 180 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
176 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 181 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
177 PERF_OUTPUT_PERIOD | PERF_OUTPUT_ADDR | 182 PERF_OUTPUT_PERIOD | PERF_OUTPUT_ADDR |
178 PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT, 183 PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT |
184 PERF_OUTPUT_PHYS_ADDR,
179 185
180 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 186 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
181 }, 187 },
@@ -205,6 +211,51 @@ static struct {
205 }, 211 },
206}; 212};
207 213
214struct perf_evsel_script {
215 char *filename;
216 FILE *fp;
217 u64 samples;
218};
219
220static struct perf_evsel_script *perf_evsel_script__new(struct perf_evsel *evsel,
221 struct perf_data *data)
222{
223 struct perf_evsel_script *es = malloc(sizeof(*es));
224
225 if (es != NULL) {
226 if (asprintf(&es->filename, "%s.%s.dump", data->file.path, perf_evsel__name(evsel)) < 0)
227 goto out_free;
228 es->fp = fopen(es->filename, "w");
229 if (es->fp == NULL)
230 goto out_free_filename;
231 es->samples = 0;
232 }
233
234 return es;
235out_free_filename:
236 zfree(&es->filename);
237out_free:
238 free(es);
239 return NULL;
240}
241
242static void perf_evsel_script__delete(struct perf_evsel_script *es)
243{
244 zfree(&es->filename);
245 fclose(es->fp);
246 es->fp = NULL;
247 free(es);
248}
249
250static int perf_evsel_script__fprintf(struct perf_evsel_script *es, FILE *fp)
251{
252 struct stat st;
253
254 fstat(fileno(es->fp), &st);
255 return fprintf(fp, "[ perf script: Wrote %.3f MB %s (%" PRIu64 " samples) ]\n",
256 st.st_size / 1024.0 / 1024.0, es->filename, es->samples);
257}
258
208static inline int output_type(unsigned int type) 259static inline int output_type(unsigned int type)
209{ 260{
210 switch (type) { 261 switch (type) {
@@ -382,6 +433,16 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
382 PERF_OUTPUT_IREGS)) 433 PERF_OUTPUT_IREGS))
383 return -EINVAL; 434 return -EINVAL;
384 435
436 if (PRINT_FIELD(UREGS) &&
437 perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS",
438 PERF_OUTPUT_UREGS))
439 return -EINVAL;
440
441 if (PRINT_FIELD(PHYS_ADDR) &&
442 perf_evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR",
443 PERF_OUTPUT_PHYS_ADDR))
444 return -EINVAL;
445
385 return 0; 446 return 0;
386} 447}
387 448
@@ -485,51 +546,76 @@ out:
485 return 0; 546 return 0;
486} 547}
487 548
488static void print_sample_iregs(struct perf_sample *sample, 549static int perf_sample__fprintf_iregs(struct perf_sample *sample,
489 struct perf_event_attr *attr) 550 struct perf_event_attr *attr, FILE *fp)
490{ 551{
491 struct regs_dump *regs = &sample->intr_regs; 552 struct regs_dump *regs = &sample->intr_regs;
492 uint64_t mask = attr->sample_regs_intr; 553 uint64_t mask = attr->sample_regs_intr;
493 unsigned i = 0, r; 554 unsigned i = 0, r;
555 int printed = 0;
494 556
495 if (!regs) 557 if (!regs)
496 return; 558 return 0;
559
560 for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
561 u64 val = regs->regs[i++];
562 printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
563 }
564
565 return printed;
566}
567
568static int perf_sample__fprintf_uregs(struct perf_sample *sample,
569 struct perf_event_attr *attr, FILE *fp)
570{
571 struct regs_dump *regs = &sample->user_regs;
572 uint64_t mask = attr->sample_regs_user;
573 unsigned i = 0, r;
574 int printed = 0;
575
576 if (!regs || !regs->regs)
577 return 0;
578
579 printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi);
497 580
498 for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { 581 for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
499 u64 val = regs->regs[i++]; 582 u64 val = regs->regs[i++];
500 printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val); 583 printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
501 } 584 }
585
586 return printed;
502} 587}
503 588
504static void print_sample_start(struct perf_sample *sample, 589static int perf_sample__fprintf_start(struct perf_sample *sample,
505 struct thread *thread, 590 struct thread *thread,
506 struct perf_evsel *evsel) 591 struct perf_evsel *evsel, FILE *fp)
507{ 592{
508 struct perf_event_attr *attr = &evsel->attr; 593 struct perf_event_attr *attr = &evsel->attr;
509 unsigned long secs; 594 unsigned long secs;
510 unsigned long long nsecs; 595 unsigned long long nsecs;
596 int printed = 0;
511 597
512 if (PRINT_FIELD(COMM)) { 598 if (PRINT_FIELD(COMM)) {
513 if (latency_format) 599 if (latency_format)
514 printf("%8.8s ", thread__comm_str(thread)); 600 printed += fprintf(fp, "%8.8s ", thread__comm_str(thread));
515 else if (PRINT_FIELD(IP) && symbol_conf.use_callchain) 601 else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
516 printf("%s ", thread__comm_str(thread)); 602 printed += fprintf(fp, "%s ", thread__comm_str(thread));
517 else 603 else
518 printf("%16s ", thread__comm_str(thread)); 604 printed += fprintf(fp, "%16s ", thread__comm_str(thread));
519 } 605 }
520 606
521 if (PRINT_FIELD(PID) && PRINT_FIELD(TID)) 607 if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
522 printf("%5d/%-5d ", sample->pid, sample->tid); 608 printed += fprintf(fp, "%5d/%-5d ", sample->pid, sample->tid);
523 else if (PRINT_FIELD(PID)) 609 else if (PRINT_FIELD(PID))
524 printf("%5d ", sample->pid); 610 printed += fprintf(fp, "%5d ", sample->pid);
525 else if (PRINT_FIELD(TID)) 611 else if (PRINT_FIELD(TID))
526 printf("%5d ", sample->tid); 612 printed += fprintf(fp, "%5d ", sample->tid);
527 613
528 if (PRINT_FIELD(CPU)) { 614 if (PRINT_FIELD(CPU)) {
529 if (latency_format) 615 if (latency_format)
530 printf("%3d ", sample->cpu); 616 printed += fprintf(fp, "%3d ", sample->cpu);
531 else 617 else
532 printf("[%03d] ", sample->cpu); 618 printed += fprintf(fp, "[%03d] ", sample->cpu);
533 } 619 }
534 620
535 if (PRINT_FIELD(TIME)) { 621 if (PRINT_FIELD(TIME)) {
@@ -538,13 +624,15 @@ static void print_sample_start(struct perf_sample *sample,
538 nsecs -= secs * NSEC_PER_SEC; 624 nsecs -= secs * NSEC_PER_SEC;
539 625
540 if (nanosecs) 626 if (nanosecs)
541 printf("%5lu.%09llu: ", secs, nsecs); 627 printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs);
542 else { 628 else {
543 char sample_time[32]; 629 char sample_time[32];
544 timestamp__scnprintf_usec(sample->time, sample_time, sizeof(sample_time)); 630 timestamp__scnprintf_usec(sample->time, sample_time, sizeof(sample_time));
545 printf("%12s: ", sample_time); 631 printed += fprintf(fp, "%12s: ", sample_time);
546 } 632 }
547 } 633 }
634
635 return printed;
548} 636}
549 637
550static inline char 638static inline char
@@ -556,16 +644,17 @@ mispred_str(struct branch_entry *br)
556 return br->flags.predicted ? 'P' : 'M'; 644 return br->flags.predicted ? 'P' : 'M';
557} 645}
558 646
559static void print_sample_brstack(struct perf_sample *sample, 647static int perf_sample__fprintf_brstack(struct perf_sample *sample,
560 struct thread *thread, 648 struct thread *thread,
561 struct perf_event_attr *attr) 649 struct perf_event_attr *attr, FILE *fp)
562{ 650{
563 struct branch_stack *br = sample->branch_stack; 651 struct branch_stack *br = sample->branch_stack;
564 struct addr_location alf, alt; 652 struct addr_location alf, alt;
565 u64 i, from, to; 653 u64 i, from, to;
654 int printed = 0;
566 655
567 if (!(br && br->nr)) 656 if (!(br && br->nr))
568 return; 657 return 0;
569 658
570 for (i = 0; i < br->nr; i++) { 659 for (i = 0; i < br->nr; i++) {
571 from = br->entries[i].from; 660 from = br->entries[i].from;
@@ -578,38 +667,41 @@ static void print_sample_brstack(struct perf_sample *sample,
578 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt); 667 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
579 } 668 }
580 669
581 printf("0x%"PRIx64, from); 670 printed += fprintf(fp, " 0x%"PRIx64, from);
582 if (PRINT_FIELD(DSO)) { 671 if (PRINT_FIELD(DSO)) {
583 printf("("); 672 printed += fprintf(fp, "(");
584 map__fprintf_dsoname(alf.map, stdout); 673 printed += map__fprintf_dsoname(alf.map, fp);
585 printf(")"); 674 printed += fprintf(fp, ")");
586 } 675 }
587 676
588 printf("/0x%"PRIx64, to); 677 printed += fprintf(fp, "/0x%"PRIx64, to);
589 if (PRINT_FIELD(DSO)) { 678 if (PRINT_FIELD(DSO)) {
590 printf("("); 679 printed += fprintf(fp, "(");
591 map__fprintf_dsoname(alt.map, stdout); 680 printed += map__fprintf_dsoname(alt.map, fp);
592 printf(")"); 681 printed += fprintf(fp, ")");
593 } 682 }
594 683
595 printf("/%c/%c/%c/%d ", 684 printed += fprintf(fp, "/%c/%c/%c/%d ",
596 mispred_str( br->entries + i), 685 mispred_str( br->entries + i),
597 br->entries[i].flags.in_tx? 'X' : '-', 686 br->entries[i].flags.in_tx? 'X' : '-',
598 br->entries[i].flags.abort? 'A' : '-', 687 br->entries[i].flags.abort? 'A' : '-',
599 br->entries[i].flags.cycles); 688 br->entries[i].flags.cycles);
600 } 689 }
690
691 return printed;
601} 692}
602 693
603static void print_sample_brstacksym(struct perf_sample *sample, 694static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
604 struct thread *thread, 695 struct thread *thread,
605 struct perf_event_attr *attr) 696 struct perf_event_attr *attr, FILE *fp)
606{ 697{
607 struct branch_stack *br = sample->branch_stack; 698 struct branch_stack *br = sample->branch_stack;
608 struct addr_location alf, alt; 699 struct addr_location alf, alt;
609 u64 i, from, to; 700 u64 i, from, to;
701 int printed = 0;
610 702
611 if (!(br && br->nr)) 703 if (!(br && br->nr))
612 return; 704 return 0;
613 705
614 for (i = 0; i < br->nr; i++) { 706 for (i = 0; i < br->nr; i++) {
615 707
@@ -626,37 +718,40 @@ static void print_sample_brstacksym(struct perf_sample *sample,
626 if (alt.map) 718 if (alt.map)
627 alt.sym = map__find_symbol(alt.map, alt.addr); 719 alt.sym = map__find_symbol(alt.map, alt.addr);
628 720
629 symbol__fprintf_symname_offs(alf.sym, &alf, stdout); 721 printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
630 if (PRINT_FIELD(DSO)) { 722 if (PRINT_FIELD(DSO)) {
631 printf("("); 723 printed += fprintf(fp, "(");
632 map__fprintf_dsoname(alf.map, stdout); 724 printed += map__fprintf_dsoname(alf.map, fp);
633 printf(")"); 725 printed += fprintf(fp, ")");
634 } 726 }
635 putchar('/'); 727 printed += fprintf(fp, "%c", '/');
636 symbol__fprintf_symname_offs(alt.sym, &alt, stdout); 728 printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp);
637 if (PRINT_FIELD(DSO)) { 729 if (PRINT_FIELD(DSO)) {
638 printf("("); 730 printed += fprintf(fp, "(");
639 map__fprintf_dsoname(alt.map, stdout); 731 printed += map__fprintf_dsoname(alt.map, fp);
640 printf(")"); 732 printed += fprintf(fp, ")");
641 } 733 }
642 printf("/%c/%c/%c/%d ", 734 printed += fprintf(fp, "/%c/%c/%c/%d ",
643 mispred_str( br->entries + i), 735 mispred_str( br->entries + i),
644 br->entries[i].flags.in_tx? 'X' : '-', 736 br->entries[i].flags.in_tx? 'X' : '-',
645 br->entries[i].flags.abort? 'A' : '-', 737 br->entries[i].flags.abort? 'A' : '-',
646 br->entries[i].flags.cycles); 738 br->entries[i].flags.cycles);
647 } 739 }
740
741 return printed;
648} 742}
649 743
650static void print_sample_brstackoff(struct perf_sample *sample, 744static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
651 struct thread *thread, 745 struct thread *thread,
652 struct perf_event_attr *attr) 746 struct perf_event_attr *attr, FILE *fp)
653{ 747{
654 struct branch_stack *br = sample->branch_stack; 748 struct branch_stack *br = sample->branch_stack;
655 struct addr_location alf, alt; 749 struct addr_location alf, alt;
656 u64 i, from, to; 750 u64 i, from, to;
751 int printed = 0;
657 752
658 if (!(br && br->nr)) 753 if (!(br && br->nr))
659 return; 754 return 0;
660 755
661 for (i = 0; i < br->nr; i++) { 756 for (i = 0; i < br->nr; i++) {
662 757
@@ -673,24 +768,26 @@ static void print_sample_brstackoff(struct perf_sample *sample,
673 if (alt.map && !alt.map->dso->adjust_symbols) 768 if (alt.map && !alt.map->dso->adjust_symbols)
674 to = map__map_ip(alt.map, to); 769 to = map__map_ip(alt.map, to);
675 770
676 printf("0x%"PRIx64, from); 771 printed += fprintf(fp, " 0x%"PRIx64, from);
677 if (PRINT_FIELD(DSO)) { 772 if (PRINT_FIELD(DSO)) {
678 printf("("); 773 printed += fprintf(fp, "(");
679 map__fprintf_dsoname(alf.map, stdout); 774 printed += map__fprintf_dsoname(alf.map, fp);
680 printf(")"); 775 printed += fprintf(fp, ")");
681 } 776 }
682 printf("/0x%"PRIx64, to); 777 printed += fprintf(fp, "/0x%"PRIx64, to);
683 if (PRINT_FIELD(DSO)) { 778 if (PRINT_FIELD(DSO)) {
684 printf("("); 779 printed += fprintf(fp, "(");
685 map__fprintf_dsoname(alt.map, stdout); 780 printed += map__fprintf_dsoname(alt.map, fp);
686 printf(")"); 781 printed += fprintf(fp, ")");
687 } 782 }
688 printf("/%c/%c/%c/%d ", 783 printed += fprintf(fp, "/%c/%c/%c/%d ",
689 mispred_str(br->entries + i), 784 mispred_str(br->entries + i),
690 br->entries[i].flags.in_tx ? 'X' : '-', 785 br->entries[i].flags.in_tx ? 'X' : '-',
691 br->entries[i].flags.abort ? 'A' : '-', 786 br->entries[i].flags.abort ? 'A' : '-',
692 br->entries[i].flags.cycles); 787 br->entries[i].flags.cycles);
693 } 788 }
789
790 return printed;
694} 791}
695#define MAXBB 16384UL 792#define MAXBB 16384UL
696 793
@@ -718,27 +815,26 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
718 * but the exit is not. Let the caller patch it up. 815 * but the exit is not. Let the caller patch it up.
719 */ 816 */
720 if (kernel != machine__kernel_ip(machine, end)) { 817 if (kernel != machine__kernel_ip(machine, end)) {
721 printf("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", 818 pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end);
722 start, end);
723 return -ENXIO; 819 return -ENXIO;
724 } 820 }
725 821
726 memset(&al, 0, sizeof(al)); 822 memset(&al, 0, sizeof(al));
727 if (end - start > MAXBB - MAXINSN) { 823 if (end - start > MAXBB - MAXINSN) {
728 if (last) 824 if (last)
729 printf("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end); 825 pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end);
730 else 826 else
731 printf("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start); 827 pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start);
732 return 0; 828 return 0;
733 } 829 }
734 830
735 thread__find_addr_map(thread, *cpumode, MAP__FUNCTION, start, &al); 831 thread__find_addr_map(thread, *cpumode, MAP__FUNCTION, start, &al);
736 if (!al.map || !al.map->dso) { 832 if (!al.map || !al.map->dso) {
737 printf("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); 833 pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
738 return 0; 834 return 0;
739 } 835 }
740 if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) { 836 if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) {
741 printf("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); 837 pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
742 return 0; 838 return 0;
743 } 839 }
744 840
@@ -751,36 +847,35 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
751 847
752 *is64bit = al.map->dso->is_64_bit; 848 *is64bit = al.map->dso->is_64_bit;
753 if (len <= 0) 849 if (len <= 0)
754 printf("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n", 850 pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
755 start, end); 851 start, end);
756 return len; 852 return len;
757} 853}
758 854
759static void print_jump(uint64_t ip, struct branch_entry *en, 855static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
760 struct perf_insn *x, u8 *inbuf, int len, 856 struct perf_insn *x, u8 *inbuf, int len,
761 int insn) 857 int insn, FILE *fp)
762{ 858{
763 printf("\t%016" PRIx64 "\t%-30s\t#%s%s%s%s", 859 int printed = fprintf(fp, "\t%016" PRIx64 "\t%-30s\t#%s%s%s%s", ip,
764 ip, 860 dump_insn(x, ip, inbuf, len, NULL),
765 dump_insn(x, ip, inbuf, len, NULL), 861 en->flags.predicted ? " PRED" : "",
766 en->flags.predicted ? " PRED" : "", 862 en->flags.mispred ? " MISPRED" : "",
767 en->flags.mispred ? " MISPRED" : "", 863 en->flags.in_tx ? " INTX" : "",
768 en->flags.in_tx ? " INTX" : "", 864 en->flags.abort ? " ABORT" : "");
769 en->flags.abort ? " ABORT" : "");
770 if (en->flags.cycles) { 865 if (en->flags.cycles) {
771 printf(" %d cycles", en->flags.cycles); 866 printed += fprintf(fp, " %d cycles", en->flags.cycles);
772 if (insn) 867 if (insn)
773 printf(" %.2f IPC", (float)insn / en->flags.cycles); 868 printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
774 } 869 }
775 putchar('\n'); 870 return printed + fprintf(fp, "\n");
776} 871}
777 872
778static void print_ip_sym(struct thread *thread, u8 cpumode, int cpu, 873static int ip__fprintf_sym(uint64_t addr, struct thread *thread,
779 uint64_t addr, struct symbol **lastsym, 874 u8 cpumode, int cpu, struct symbol **lastsym,
780 struct perf_event_attr *attr) 875 struct perf_event_attr *attr, FILE *fp)
781{ 876{
782 struct addr_location al; 877 struct addr_location al;
783 int off; 878 int off, printed = 0;
784 879
785 memset(&al, 0, sizeof(al)); 880 memset(&al, 0, sizeof(al));
786 881
@@ -789,7 +884,7 @@ static void print_ip_sym(struct thread *thread, u8 cpumode, int cpu,
789 thread__find_addr_map(thread, cpumode, MAP__VARIABLE, 884 thread__find_addr_map(thread, cpumode, MAP__VARIABLE,
790 addr, &al); 885 addr, &al);
791 if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end) 886 if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
792 return; 887 return 0;
793 888
794 al.cpu = cpu; 889 al.cpu = cpu;
795 al.sym = NULL; 890 al.sym = NULL;
@@ -797,37 +892,39 @@ static void print_ip_sym(struct thread *thread, u8 cpumode, int cpu,
797 al.sym = map__find_symbol(al.map, al.addr); 892 al.sym = map__find_symbol(al.map, al.addr);
798 893
799 if (!al.sym) 894 if (!al.sym)
800 return; 895 return 0;
801 896
802 if (al.addr < al.sym->end) 897 if (al.addr < al.sym->end)
803 off = al.addr - al.sym->start; 898 off = al.addr - al.sym->start;
804 else 899 else
805 off = al.addr - al.map->start - al.sym->start; 900 off = al.addr - al.map->start - al.sym->start;
806 printf("\t%s", al.sym->name); 901 printed += fprintf(fp, "\t%s", al.sym->name);
807 if (off) 902 if (off)
808 printf("%+d", off); 903 printed += fprintf(fp, "%+d", off);
809 putchar(':'); 904 printed += fprintf(fp, ":");
810 if (PRINT_FIELD(SRCLINE)) 905 if (PRINT_FIELD(SRCLINE))
811 map__fprintf_srcline(al.map, al.addr, "\t", stdout); 906 printed += map__fprintf_srcline(al.map, al.addr, "\t", fp);
812 putchar('\n'); 907 printed += fprintf(fp, "\n");
813 *lastsym = al.sym; 908 *lastsym = al.sym;
909
910 return printed;
814} 911}
815 912
816static void print_sample_brstackinsn(struct perf_sample *sample, 913static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
817 struct thread *thread, 914 struct thread *thread,
818 struct perf_event_attr *attr, 915 struct perf_event_attr *attr,
819 struct machine *machine) 916 struct machine *machine, FILE *fp)
820{ 917{
821 struct branch_stack *br = sample->branch_stack; 918 struct branch_stack *br = sample->branch_stack;
822 u64 start, end; 919 u64 start, end;
823 int i, insn, len, nr, ilen; 920 int i, insn, len, nr, ilen, printed = 0;
824 struct perf_insn x; 921 struct perf_insn x;
825 u8 buffer[MAXBB]; 922 u8 buffer[MAXBB];
826 unsigned off; 923 unsigned off;
827 struct symbol *lastsym = NULL; 924 struct symbol *lastsym = NULL;
828 925
829 if (!(br && br->nr)) 926 if (!(br && br->nr))
830 return; 927 return 0;
831 nr = br->nr; 928 nr = br->nr;
832 if (max_blocks && nr > max_blocks + 1) 929 if (max_blocks && nr > max_blocks + 1)
833 nr = max_blocks + 1; 930 nr = max_blocks + 1;
@@ -835,17 +932,17 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
835 x.thread = thread; 932 x.thread = thread;
836 x.cpu = sample->cpu; 933 x.cpu = sample->cpu;
837 934
838 putchar('\n'); 935 printed += fprintf(fp, "%c", '\n');
839 936
840 /* Handle first from jump, of which we don't know the entry. */ 937 /* Handle first from jump, of which we don't know the entry. */
841 len = grab_bb(buffer, br->entries[nr-1].from, 938 len = grab_bb(buffer, br->entries[nr-1].from,
842 br->entries[nr-1].from, 939 br->entries[nr-1].from,
843 machine, thread, &x.is64bit, &x.cpumode, false); 940 machine, thread, &x.is64bit, &x.cpumode, false);
844 if (len > 0) { 941 if (len > 0) {
845 print_ip_sym(thread, x.cpumode, x.cpu, 942 printed += ip__fprintf_sym(br->entries[nr - 1].from, thread,
846 br->entries[nr - 1].from, &lastsym, attr); 943 x.cpumode, x.cpu, &lastsym, attr, fp);
847 print_jump(br->entries[nr - 1].from, &br->entries[nr - 1], 944 printed += ip__fprintf_jump(br->entries[nr - 1].from, &br->entries[nr - 1],
848 &x, buffer, len, 0); 945 &x, buffer, len, 0, fp);
849 } 946 }
850 947
851 /* Print all blocks */ 948 /* Print all blocks */
@@ -871,13 +968,13 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
871 for (off = 0;; off += ilen) { 968 for (off = 0;; off += ilen) {
872 uint64_t ip = start + off; 969 uint64_t ip = start + off;
873 970
874 print_ip_sym(thread, x.cpumode, x.cpu, ip, &lastsym, attr); 971 printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
875 if (ip == end) { 972 if (ip == end) {
876 print_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn); 973 printed += ip__fprintf_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn, fp);
877 break; 974 break;
878 } else { 975 } else {
879 printf("\t%016" PRIx64 "\t%s\n", ip, 976 printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip,
880 dump_insn(&x, ip, buffer + off, len - off, &ilen)); 977 dump_insn(&x, ip, buffer + off, len - off, &ilen));
881 if (ilen == 0) 978 if (ilen == 0)
882 break; 979 break;
883 insn++; 980 insn++;
@@ -890,9 +987,9 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
890 * has not been executed yet. 987 * has not been executed yet.
891 */ 988 */
892 if (br->entries[0].from == sample->ip) 989 if (br->entries[0].from == sample->ip)
893 return; 990 goto out;
894 if (br->entries[0].flags.abort) 991 if (br->entries[0].flags.abort)
895 return; 992 goto out;
896 993
897 /* 994 /*
898 * Print final block upto sample 995 * Print final block upto sample
@@ -900,58 +997,61 @@ static void print_sample_brstackinsn(struct perf_sample *sample,
900 start = br->entries[0].to; 997 start = br->entries[0].to;
901 end = sample->ip; 998 end = sample->ip;
902 len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true); 999 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); 1000 printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
904 if (len <= 0) { 1001 if (len <= 0) {
905 /* Print at least last IP if basic block did not work */ 1002 /* Print at least last IP if basic block did not work */
906 len = grab_bb(buffer, sample->ip, sample->ip, 1003 len = grab_bb(buffer, sample->ip, sample->ip,
907 machine, thread, &x.is64bit, &x.cpumode, false); 1004 machine, thread, &x.is64bit, &x.cpumode, false);
908 if (len <= 0) 1005 if (len <= 0)
909 return; 1006 goto out;
910 1007
911 printf("\t%016" PRIx64 "\t%s\n", sample->ip, 1008 printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip,
912 dump_insn(&x, sample->ip, buffer, len, NULL)); 1009 dump_insn(&x, sample->ip, buffer, len, NULL));
913 return; 1010 goto out;
914 } 1011 }
915 for (off = 0; off <= end - start; off += ilen) { 1012 for (off = 0; off <= end - start; off += ilen) {
916 printf("\t%016" PRIx64 "\t%s\n", start + off, 1013 printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", start + off,
917 dump_insn(&x, start + off, buffer + off, len - off, &ilen)); 1014 dump_insn(&x, start + off, buffer + off, len - off, &ilen));
918 if (ilen == 0) 1015 if (ilen == 0)
919 break; 1016 break;
920 } 1017 }
1018out:
1019 return printed;
921} 1020}
922 1021
923static void print_sample_addr(struct perf_sample *sample, 1022static int perf_sample__fprintf_addr(struct perf_sample *sample,
924 struct thread *thread, 1023 struct thread *thread,
925 struct perf_event_attr *attr) 1024 struct perf_event_attr *attr, FILE *fp)
926{ 1025{
927 struct addr_location al; 1026 struct addr_location al;
928 1027 int printed = fprintf(fp, "%16" PRIx64, sample->addr);
929 printf("%16" PRIx64, sample->addr);
930 1028
931 if (!sample_addr_correlates_sym(attr)) 1029 if (!sample_addr_correlates_sym(attr))
932 return; 1030 goto out;
933 1031
934 thread__resolve(thread, &al, sample); 1032 thread__resolve(thread, &al, sample);
935 1033
936 if (PRINT_FIELD(SYM)) { 1034 if (PRINT_FIELD(SYM)) {
937 printf(" "); 1035 printed += fprintf(fp, " ");
938 if (PRINT_FIELD(SYMOFFSET)) 1036 if (PRINT_FIELD(SYMOFFSET))
939 symbol__fprintf_symname_offs(al.sym, &al, stdout); 1037 printed += symbol__fprintf_symname_offs(al.sym, &al, fp);
940 else 1038 else
941 symbol__fprintf_symname(al.sym, stdout); 1039 printed += symbol__fprintf_symname(al.sym, fp);
942 } 1040 }
943 1041
944 if (PRINT_FIELD(DSO)) { 1042 if (PRINT_FIELD(DSO)) {
945 printf(" ("); 1043 printed += fprintf(fp, " (");
946 map__fprintf_dsoname(al.map, stdout); 1044 printed += map__fprintf_dsoname(al.map, fp);
947 printf(")"); 1045 printed += fprintf(fp, ")");
948 } 1046 }
1047out:
1048 return printed;
949} 1049}
950 1050
951static void print_sample_callindent(struct perf_sample *sample, 1051static int perf_sample__fprintf_callindent(struct perf_sample *sample,
952 struct perf_evsel *evsel, 1052 struct perf_evsel *evsel,
953 struct thread *thread, 1053 struct thread *thread,
954 struct addr_location *al) 1054 struct addr_location *al, FILE *fp)
955{ 1055{
956 struct perf_event_attr *attr = &evsel->attr; 1056 struct perf_event_attr *attr = &evsel->attr;
957 size_t depth = thread_stack__depth(thread); 1057 size_t depth = thread_stack__depth(thread);
@@ -986,12 +1086,12 @@ static void print_sample_callindent(struct perf_sample *sample,
986 } 1086 }
987 1087
988 if (name) 1088 if (name)
989 len = printf("%*s%s", (int)depth * 4, "", name); 1089 len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);
990 else if (ip) 1090 else if (ip)
991 len = printf("%*s%16" PRIx64, (int)depth * 4, "", ip); 1091 len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip);
992 1092
993 if (len < 0) 1093 if (len < 0)
994 return; 1094 return len;
995 1095
996 /* 1096 /*
997 * Try to keep the output length from changing frequently so that the 1097 * Try to keep the output length from changing frequently so that the
@@ -1001,39 +1101,46 @@ static void print_sample_callindent(struct perf_sample *sample,
1001 spacing = round_up(len + 4, 32); 1101 spacing = round_up(len + 4, 32);
1002 1102
1003 if (len < spacing) 1103 if (len < spacing)
1004 printf("%*s", spacing - len, ""); 1104 len += fprintf(fp, "%*s", spacing - len, "");
1105
1106 return len;
1005} 1107}
1006 1108
1007static void print_insn(struct perf_sample *sample, 1109static int perf_sample__fprintf_insn(struct perf_sample *sample,
1008 struct perf_event_attr *attr, 1110 struct perf_event_attr *attr,
1009 struct thread *thread, 1111 struct thread *thread,
1010 struct machine *machine) 1112 struct machine *machine, FILE *fp)
1011{ 1113{
1114 int printed = 0;
1115
1012 if (PRINT_FIELD(INSNLEN)) 1116 if (PRINT_FIELD(INSNLEN))
1013 printf(" ilen: %d", sample->insn_len); 1117 printed += fprintf(fp, " ilen: %d", sample->insn_len);
1014 if (PRINT_FIELD(INSN)) { 1118 if (PRINT_FIELD(INSN)) {
1015 int i; 1119 int i;
1016 1120
1017 printf(" insn:"); 1121 printed += fprintf(fp, " insn:");
1018 for (i = 0; i < sample->insn_len; i++) 1122 for (i = 0; i < sample->insn_len; i++)
1019 printf(" %02x", (unsigned char)sample->insn[i]); 1123 printed += fprintf(fp, " %02x", (unsigned char)sample->insn[i]);
1020 } 1124 }
1021 if (PRINT_FIELD(BRSTACKINSN)) 1125 if (PRINT_FIELD(BRSTACKINSN))
1022 print_sample_brstackinsn(sample, thread, attr, machine); 1126 printed += perf_sample__fprintf_brstackinsn(sample, thread, attr, machine, fp);
1127
1128 return printed;
1023} 1129}
1024 1130
1025static void print_sample_bts(struct perf_sample *sample, 1131static int perf_sample__fprintf_bts(struct perf_sample *sample,
1026 struct perf_evsel *evsel, 1132 struct perf_evsel *evsel,
1027 struct thread *thread, 1133 struct thread *thread,
1028 struct addr_location *al, 1134 struct addr_location *al,
1029 struct machine *machine) 1135 struct machine *machine, FILE *fp)
1030{ 1136{
1031 struct perf_event_attr *attr = &evsel->attr; 1137 struct perf_event_attr *attr = &evsel->attr;
1032 unsigned int type = output_type(attr->type); 1138 unsigned int type = output_type(attr->type);
1033 bool print_srcline_last = false; 1139 bool print_srcline_last = false;
1140 int printed = 0;
1034 1141
1035 if (PRINT_FIELD(CALLINDENT)) 1142 if (PRINT_FIELD(CALLINDENT))
1036 print_sample_callindent(sample, evsel, thread, al); 1143 printed += perf_sample__fprintf_callindent(sample, evsel, thread, al, fp);
1037 1144
1038 /* print branch_from information */ 1145 /* print branch_from information */
1039 if (PRINT_FIELD(IP)) { 1146 if (PRINT_FIELD(IP)) {
@@ -1046,31 +1153,30 @@ static void print_sample_bts(struct perf_sample *sample,
1046 cursor = &callchain_cursor; 1153 cursor = &callchain_cursor;
1047 1154
1048 if (cursor == NULL) { 1155 if (cursor == NULL) {
1049 putchar(' '); 1156 printed += fprintf(fp, " ");
1050 if (print_opts & EVSEL__PRINT_SRCLINE) { 1157 if (print_opts & EVSEL__PRINT_SRCLINE) {
1051 print_srcline_last = true; 1158 print_srcline_last = true;
1052 print_opts &= ~EVSEL__PRINT_SRCLINE; 1159 print_opts &= ~EVSEL__PRINT_SRCLINE;
1053 } 1160 }
1054 } else 1161 } else
1055 putchar('\n'); 1162 printed += fprintf(fp, "\n");
1056 1163
1057 sample__fprintf_sym(sample, al, 0, print_opts, cursor, stdout); 1164 printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor, fp);
1058 } 1165 }
1059 1166
1060 /* print branch_to information */ 1167 /* print branch_to information */
1061 if (PRINT_FIELD(ADDR) || 1168 if (PRINT_FIELD(ADDR) ||
1062 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && 1169 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
1063 !output[type].user_set)) { 1170 !output[type].user_set)) {
1064 printf(" => "); 1171 printed += fprintf(fp, " => ");
1065 print_sample_addr(sample, thread, attr); 1172 printed += perf_sample__fprintf_addr(sample, thread, attr, fp);
1066 } 1173 }
1067 1174
1068 if (print_srcline_last) 1175 if (print_srcline_last)
1069 map__fprintf_srcline(al->map, al->addr, "\n ", stdout); 1176 printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp);
1070
1071 print_insn(sample, attr, thread, machine);
1072 1177
1073 printf("\n"); 1178 printed += perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
1179 return printed + fprintf(fp, "\n");
1074} 1180}
1075 1181
1076static struct { 1182static struct {
@@ -1093,7 +1199,7 @@ static struct {
1093 {0, NULL} 1199 {0, NULL}
1094}; 1200};
1095 1201
1096static void print_sample_flags(u32 flags) 1202static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
1097{ 1203{
1098 const char *chars = PERF_IP_FLAG_CHARS; 1204 const char *chars = PERF_IP_FLAG_CHARS;
1099 const int n = strlen(PERF_IP_FLAG_CHARS); 1205 const int n = strlen(PERF_IP_FLAG_CHARS);
@@ -1120,9 +1226,9 @@ static void print_sample_flags(u32 flags)
1120 str[pos] = 0; 1226 str[pos] = 0;
1121 1227
1122 if (name) 1228 if (name)
1123 printf(" %-7s%4s ", name, in_tx ? "(x)" : ""); 1229 return fprintf(fp, " %-7s%4s ", name, in_tx ? "(x)" : "");
1124 else 1230
1125 printf(" %-11s ", str); 1231 return fprintf(fp, " %-11s ", str);
1126} 1232}
1127 1233
1128struct printer_data { 1234struct printer_data {
@@ -1131,40 +1237,40 @@ struct printer_data {
1131 bool is_printable; 1237 bool is_printable;
1132}; 1238};
1133 1239
1134static void 1240static int sample__fprintf_bpf_output(enum binary_printer_ops op,
1135print_sample_bpf_output_printer(enum binary_printer_ops op, 1241 unsigned int val,
1136 unsigned int val, 1242 void *extra, FILE *fp)
1137 void *extra)
1138{ 1243{
1139 unsigned char ch = (unsigned char)val; 1244 unsigned char ch = (unsigned char)val;
1140 struct printer_data *printer_data = extra; 1245 struct printer_data *printer_data = extra;
1246 int printed = 0;
1141 1247
1142 switch (op) { 1248 switch (op) {
1143 case BINARY_PRINT_DATA_BEGIN: 1249 case BINARY_PRINT_DATA_BEGIN:
1144 printf("\n"); 1250 printed += fprintf(fp, "\n");
1145 break; 1251 break;
1146 case BINARY_PRINT_LINE_BEGIN: 1252 case BINARY_PRINT_LINE_BEGIN:
1147 printf("%17s", !printer_data->line_no ? "BPF output:" : 1253 printed += fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" :
1148 " "); 1254 " ");
1149 break; 1255 break;
1150 case BINARY_PRINT_ADDR: 1256 case BINARY_PRINT_ADDR:
1151 printf(" %04x:", val); 1257 printed += fprintf(fp, " %04x:", val);
1152 break; 1258 break;
1153 case BINARY_PRINT_NUM_DATA: 1259 case BINARY_PRINT_NUM_DATA:
1154 printf(" %02x", val); 1260 printed += fprintf(fp, " %02x", val);
1155 break; 1261 break;
1156 case BINARY_PRINT_NUM_PAD: 1262 case BINARY_PRINT_NUM_PAD:
1157 printf(" "); 1263 printed += fprintf(fp, " ");
1158 break; 1264 break;
1159 case BINARY_PRINT_SEP: 1265 case BINARY_PRINT_SEP:
1160 printf(" "); 1266 printed += fprintf(fp, " ");
1161 break; 1267 break;
1162 case BINARY_PRINT_CHAR_DATA: 1268 case BINARY_PRINT_CHAR_DATA:
1163 if (printer_data->hit_nul && ch) 1269 if (printer_data->hit_nul && ch)
1164 printer_data->is_printable = false; 1270 printer_data->is_printable = false;
1165 1271
1166 if (!isprint(ch)) { 1272 if (!isprint(ch)) {
1167 printf("%c", '.'); 1273 printed += fprintf(fp, "%c", '.');
1168 1274
1169 if (!printer_data->is_printable) 1275 if (!printer_data->is_printable)
1170 break; 1276 break;
@@ -1174,154 +1280,154 @@ print_sample_bpf_output_printer(enum binary_printer_ops op,
1174 else 1280 else
1175 printer_data->is_printable = false; 1281 printer_data->is_printable = false;
1176 } else { 1282 } else {
1177 printf("%c", ch); 1283 printed += fprintf(fp, "%c", ch);
1178 } 1284 }
1179 break; 1285 break;
1180 case BINARY_PRINT_CHAR_PAD: 1286 case BINARY_PRINT_CHAR_PAD:
1181 printf(" "); 1287 printed += fprintf(fp, " ");
1182 break; 1288 break;
1183 case BINARY_PRINT_LINE_END: 1289 case BINARY_PRINT_LINE_END:
1184 printf("\n"); 1290 printed += fprintf(fp, "\n");
1185 printer_data->line_no++; 1291 printer_data->line_no++;
1186 break; 1292 break;
1187 case BINARY_PRINT_DATA_END: 1293 case BINARY_PRINT_DATA_END:
1188 default: 1294 default:
1189 break; 1295 break;
1190 } 1296 }
1297
1298 return printed;
1191} 1299}
1192 1300
1193static void print_sample_bpf_output(struct perf_sample *sample) 1301static int perf_sample__fprintf_bpf_output(struct perf_sample *sample, FILE *fp)
1194{ 1302{
1195 unsigned int nr_bytes = sample->raw_size; 1303 unsigned int nr_bytes = sample->raw_size;
1196 struct printer_data printer_data = {0, false, true}; 1304 struct printer_data printer_data = {0, false, true};
1197 1305 int printed = binary__fprintf(sample->raw_data, nr_bytes, 8,
1198 print_binary(sample->raw_data, nr_bytes, 8, 1306 sample__fprintf_bpf_output, &printer_data, fp);
1199 print_sample_bpf_output_printer, &printer_data);
1200 1307
1201 if (printer_data.is_printable && printer_data.hit_nul) 1308 if (printer_data.is_printable && printer_data.hit_nul)
1202 printf("%17s \"%s\"\n", "BPF string:", 1309 printed += fprintf(fp, "%17s \"%s\"\n", "BPF string:", (char *)(sample->raw_data));
1203 (char *)(sample->raw_data)); 1310
1311 return printed;
1204} 1312}
1205 1313
1206static void print_sample_spacing(int len, int spacing) 1314static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp)
1207{ 1315{
1208 if (len > 0 && len < spacing) 1316 if (len > 0 && len < spacing)
1209 printf("%*s", spacing - len, ""); 1317 return fprintf(fp, "%*s", spacing - len, "");
1318
1319 return 0;
1210} 1320}
1211 1321
1212static void print_sample_pt_spacing(int len) 1322static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)
1213{ 1323{
1214 print_sample_spacing(len, 34); 1324 return perf_sample__fprintf_spacing(len, 34, fp);
1215} 1325}
1216 1326
1217static void print_sample_synth_ptwrite(struct perf_sample *sample) 1327static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp)
1218{ 1328{
1219 struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample); 1329 struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
1220 int len; 1330 int len;
1221 1331
1222 if (perf_sample__bad_synth_size(sample, *data)) 1332 if (perf_sample__bad_synth_size(sample, *data))
1223 return; 1333 return 0;
1224 1334
1225 len = printf(" IP: %u payload: %#" PRIx64 " ", 1335 len = fprintf(fp, " IP: %u payload: %#" PRIx64 " ",
1226 data->ip, le64_to_cpu(data->payload)); 1336 data->ip, le64_to_cpu(data->payload));
1227 print_sample_pt_spacing(len); 1337 return len + perf_sample__fprintf_pt_spacing(len, fp);
1228} 1338}
1229 1339
1230static void print_sample_synth_mwait(struct perf_sample *sample) 1340static int perf_sample__fprintf_synth_mwait(struct perf_sample *sample, FILE *fp)
1231{ 1341{
1232 struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample); 1342 struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample);
1233 int len; 1343 int len;
1234 1344
1235 if (perf_sample__bad_synth_size(sample, *data)) 1345 if (perf_sample__bad_synth_size(sample, *data))
1236 return; 1346 return 0;
1237 1347
1238 len = printf(" hints: %#x extensions: %#x ", 1348 len = fprintf(fp, " hints: %#x extensions: %#x ",
1239 data->hints, data->extensions); 1349 data->hints, data->extensions);
1240 print_sample_pt_spacing(len); 1350 return len + perf_sample__fprintf_pt_spacing(len, fp);
1241} 1351}
1242 1352
1243static void print_sample_synth_pwre(struct perf_sample *sample) 1353static int perf_sample__fprintf_synth_pwre(struct perf_sample *sample, FILE *fp)
1244{ 1354{
1245 struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample); 1355 struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample);
1246 int len; 1356 int len;
1247 1357
1248 if (perf_sample__bad_synth_size(sample, *data)) 1358 if (perf_sample__bad_synth_size(sample, *data))
1249 return; 1359 return 0;
1250 1360
1251 len = printf(" hw: %u cstate: %u sub-cstate: %u ", 1361 len = fprintf(fp, " hw: %u cstate: %u sub-cstate: %u ",
1252 data->hw, data->cstate, data->subcstate); 1362 data->hw, data->cstate, data->subcstate);
1253 print_sample_pt_spacing(len); 1363 return len + perf_sample__fprintf_pt_spacing(len, fp);
1254} 1364}
1255 1365
1256static void print_sample_synth_exstop(struct perf_sample *sample) 1366static int perf_sample__fprintf_synth_exstop(struct perf_sample *sample, FILE *fp)
1257{ 1367{
1258 struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample); 1368 struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample);
1259 int len; 1369 int len;
1260 1370
1261 if (perf_sample__bad_synth_size(sample, *data)) 1371 if (perf_sample__bad_synth_size(sample, *data))
1262 return; 1372 return 0;
1263 1373
1264 len = printf(" IP: %u ", data->ip); 1374 len = fprintf(fp, " IP: %u ", data->ip);
1265 print_sample_pt_spacing(len); 1375 return len + perf_sample__fprintf_pt_spacing(len, fp);
1266} 1376}
1267 1377
1268static void print_sample_synth_pwrx(struct perf_sample *sample) 1378static int perf_sample__fprintf_synth_pwrx(struct perf_sample *sample, FILE *fp)
1269{ 1379{
1270 struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample); 1380 struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample);
1271 int len; 1381 int len;
1272 1382
1273 if (perf_sample__bad_synth_size(sample, *data)) 1383 if (perf_sample__bad_synth_size(sample, *data))
1274 return; 1384 return 0;
1275 1385
1276 len = printf(" deepest cstate: %u last cstate: %u wake reason: %#x ", 1386 len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ",
1277 data->deepest_cstate, data->last_cstate, 1387 data->deepest_cstate, data->last_cstate,
1278 data->wake_reason); 1388 data->wake_reason);
1279 print_sample_pt_spacing(len); 1389 return len + perf_sample__fprintf_pt_spacing(len, fp);
1280} 1390}
1281 1391
1282static void print_sample_synth_cbr(struct perf_sample *sample) 1392static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp)
1283{ 1393{
1284 struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample); 1394 struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample);
1285 unsigned int percent, freq; 1395 unsigned int percent, freq;
1286 int len; 1396 int len;
1287 1397
1288 if (perf_sample__bad_synth_size(sample, *data)) 1398 if (perf_sample__bad_synth_size(sample, *data))
1289 return; 1399 return 0;
1290 1400
1291 freq = (le32_to_cpu(data->freq) + 500) / 1000; 1401 freq = (le32_to_cpu(data->freq) + 500) / 1000;
1292 len = printf(" cbr: %2u freq: %4u MHz ", data->cbr, freq); 1402 len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
1293 if (data->max_nonturbo) { 1403 if (data->max_nonturbo) {
1294 percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10; 1404 percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
1295 len += printf("(%3u%%) ", percent); 1405 len += fprintf(fp, "(%3u%%) ", percent);
1296 } 1406 }
1297 print_sample_pt_spacing(len); 1407 return len + perf_sample__fprintf_pt_spacing(len, fp);
1298} 1408}
1299 1409
1300static void print_sample_synth(struct perf_sample *sample, 1410static int perf_sample__fprintf_synth(struct perf_sample *sample,
1301 struct perf_evsel *evsel) 1411 struct perf_evsel *evsel, FILE *fp)
1302{ 1412{
1303 switch (evsel->attr.config) { 1413 switch (evsel->attr.config) {
1304 case PERF_SYNTH_INTEL_PTWRITE: 1414 case PERF_SYNTH_INTEL_PTWRITE:
1305 print_sample_synth_ptwrite(sample); 1415 return perf_sample__fprintf_synth_ptwrite(sample, fp);
1306 break;
1307 case PERF_SYNTH_INTEL_MWAIT: 1416 case PERF_SYNTH_INTEL_MWAIT:
1308 print_sample_synth_mwait(sample); 1417 return perf_sample__fprintf_synth_mwait(sample, fp);
1309 break;
1310 case PERF_SYNTH_INTEL_PWRE: 1418 case PERF_SYNTH_INTEL_PWRE:
1311 print_sample_synth_pwre(sample); 1419 return perf_sample__fprintf_synth_pwre(sample, fp);
1312 break;
1313 case PERF_SYNTH_INTEL_EXSTOP: 1420 case PERF_SYNTH_INTEL_EXSTOP:
1314 print_sample_synth_exstop(sample); 1421 return perf_sample__fprintf_synth_exstop(sample, fp);
1315 break;
1316 case PERF_SYNTH_INTEL_PWRX: 1422 case PERF_SYNTH_INTEL_PWRX:
1317 print_sample_synth_pwrx(sample); 1423 return perf_sample__fprintf_synth_pwrx(sample, fp);
1318 break;
1319 case PERF_SYNTH_INTEL_CBR: 1424 case PERF_SYNTH_INTEL_CBR:
1320 print_sample_synth_cbr(sample); 1425 return perf_sample__fprintf_synth_cbr(sample, fp);
1321 break;
1322 default: 1426 default:
1323 break; 1427 break;
1324 } 1428 }
1429
1430 return 0;
1325} 1431}
1326 1432
1327struct perf_script { 1433struct perf_script {
@@ -1332,6 +1438,7 @@ struct perf_script {
1332 bool show_switch_events; 1438 bool show_switch_events;
1333 bool show_namespace_events; 1439 bool show_namespace_events;
1334 bool allocated; 1440 bool allocated;
1441 bool per_event_dump;
1335 struct cpu_map *cpus; 1442 struct cpu_map *cpus;
1336 struct thread_map *threads; 1443 struct thread_map *threads;
1337 int name_width; 1444 int name_width;
@@ -1353,7 +1460,7 @@ static int perf_evlist__max_name_len(struct perf_evlist *evlist)
1353 return max; 1460 return max;
1354} 1461}
1355 1462
1356static size_t data_src__printf(u64 data_src) 1463static int data_src__fprintf(u64 data_src, FILE *fp)
1357{ 1464{
1358 struct mem_info mi = { .data_src.val = data_src }; 1465 struct mem_info mi = { .data_src.val = data_src };
1359 char decode[100]; 1466 char decode[100];
@@ -1367,7 +1474,7 @@ static size_t data_src__printf(u64 data_src)
1367 if (maxlen < len) 1474 if (maxlen < len)
1368 maxlen = len; 1475 maxlen = len;
1369 1476
1370 return printf("%-*s", maxlen, out); 1477 return fprintf(fp, "%-*s", maxlen, out);
1371} 1478}
1372 1479
1373static void process_event(struct perf_script *script, 1480static void process_event(struct perf_script *script,
@@ -1378,14 +1485,18 @@ static void process_event(struct perf_script *script,
1378 struct thread *thread = al->thread; 1485 struct thread *thread = al->thread;
1379 struct perf_event_attr *attr = &evsel->attr; 1486 struct perf_event_attr *attr = &evsel->attr;
1380 unsigned int type = output_type(attr->type); 1487 unsigned int type = output_type(attr->type);
1488 struct perf_evsel_script *es = evsel->priv;
1489 FILE *fp = es->fp;
1381 1490
1382 if (output[type].fields == 0) 1491 if (output[type].fields == 0)
1383 return; 1492 return;
1384 1493
1385 print_sample_start(sample, thread, evsel); 1494 ++es->samples;
1495
1496 perf_sample__fprintf_start(sample, thread, evsel, fp);
1386 1497
1387 if (PRINT_FIELD(PERIOD)) 1498 if (PRINT_FIELD(PERIOD))
1388 printf("%10" PRIu64 " ", sample->period); 1499 fprintf(fp, "%10" PRIu64 " ", sample->period);
1389 1500
1390 if (PRINT_FIELD(EVNAME)) { 1501 if (PRINT_FIELD(EVNAME)) {
1391 const char *evname = perf_evsel__name(evsel); 1502 const char *evname = perf_evsel__name(evsel);
@@ -1393,33 +1504,33 @@ static void process_event(struct perf_script *script,
1393 if (!script->name_width) 1504 if (!script->name_width)
1394 script->name_width = perf_evlist__max_name_len(script->session->evlist); 1505 script->name_width = perf_evlist__max_name_len(script->session->evlist);
1395 1506
1396 printf("%*s: ", script->name_width, 1507 fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]");
1397 evname ? evname : "[unknown]");
1398 } 1508 }
1399 1509
1400 if (print_flags) 1510 if (print_flags)
1401 print_sample_flags(sample->flags); 1511 perf_sample__fprintf_flags(sample->flags, fp);
1402 1512
1403 if (is_bts_event(attr)) { 1513 if (is_bts_event(attr)) {
1404 print_sample_bts(sample, evsel, thread, al, machine); 1514 perf_sample__fprintf_bts(sample, evsel, thread, al, machine, fp);
1405 return; 1515 return;
1406 } 1516 }
1407 1517
1408 if (PRINT_FIELD(TRACE)) 1518 if (PRINT_FIELD(TRACE)) {
1409 event_format__print(evsel->tp_format, sample->cpu, 1519 event_format__fprintf(evsel->tp_format, sample->cpu,
1410 sample->raw_data, sample->raw_size); 1520 sample->raw_data, sample->raw_size, fp);
1521 }
1411 1522
1412 if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH)) 1523 if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
1413 print_sample_synth(sample, evsel); 1524 perf_sample__fprintf_synth(sample, evsel, fp);
1414 1525
1415 if (PRINT_FIELD(ADDR)) 1526 if (PRINT_FIELD(ADDR))
1416 print_sample_addr(sample, thread, attr); 1527 perf_sample__fprintf_addr(sample, thread, attr, fp);
1417 1528
1418 if (PRINT_FIELD(DATA_SRC)) 1529 if (PRINT_FIELD(DATA_SRC))
1419 data_src__printf(sample->data_src); 1530 data_src__fprintf(sample->data_src, fp);
1420 1531
1421 if (PRINT_FIELD(WEIGHT)) 1532 if (PRINT_FIELD(WEIGHT))
1422 printf("%16" PRIu64, sample->weight); 1533 fprintf(fp, "%16" PRIu64, sample->weight);
1423 1534
1424 if (PRINT_FIELD(IP)) { 1535 if (PRINT_FIELD(IP)) {
1425 struct callchain_cursor *cursor = NULL; 1536 struct callchain_cursor *cursor = NULL;
@@ -1429,24 +1540,30 @@ static void process_event(struct perf_script *script,
1429 sample, NULL, NULL, scripting_max_stack) == 0) 1540 sample, NULL, NULL, scripting_max_stack) == 0)
1430 cursor = &callchain_cursor; 1541 cursor = &callchain_cursor;
1431 1542
1432 putchar(cursor ? '\n' : ' '); 1543 fputc(cursor ? '\n' : ' ', fp);
1433 sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, stdout); 1544 sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, fp);
1434 } 1545 }
1435 1546
1436 if (PRINT_FIELD(IREGS)) 1547 if (PRINT_FIELD(IREGS))
1437 print_sample_iregs(sample, attr); 1548 perf_sample__fprintf_iregs(sample, attr, fp);
1549
1550 if (PRINT_FIELD(UREGS))
1551 perf_sample__fprintf_uregs(sample, attr, fp);
1438 1552
1439 if (PRINT_FIELD(BRSTACK)) 1553 if (PRINT_FIELD(BRSTACK))
1440 print_sample_brstack(sample, thread, attr); 1554 perf_sample__fprintf_brstack(sample, thread, attr, fp);
1441 else if (PRINT_FIELD(BRSTACKSYM)) 1555 else if (PRINT_FIELD(BRSTACKSYM))
1442 print_sample_brstacksym(sample, thread, attr); 1556 perf_sample__fprintf_brstacksym(sample, thread, attr, fp);
1443 else if (PRINT_FIELD(BRSTACKOFF)) 1557 else if (PRINT_FIELD(BRSTACKOFF))
1444 print_sample_brstackoff(sample, thread, attr); 1558 perf_sample__fprintf_brstackoff(sample, thread, attr, fp);
1445 1559
1446 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) 1560 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
1447 print_sample_bpf_output(sample); 1561 perf_sample__fprintf_bpf_output(sample, fp);
1448 print_insn(sample, attr, thread, machine); 1562 perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
1449 printf("\n"); 1563
1564 if (PRINT_FIELD(PHYS_ADDR))
1565 fprintf(fp, "%16" PRIx64, sample->phys_addr);
1566 fprintf(fp, "\n");
1450} 1567}
1451 1568
1452static struct scripting_ops *scripting_ops; 1569static struct scripting_ops *scripting_ops;
@@ -1620,7 +1737,7 @@ static int process_comm_event(struct perf_tool *tool,
1620 sample->tid = event->comm.tid; 1737 sample->tid = event->comm.tid;
1621 sample->pid = event->comm.pid; 1738 sample->pid = event->comm.pid;
1622 } 1739 }
1623 print_sample_start(sample, thread, evsel); 1740 perf_sample__fprintf_start(sample, thread, evsel, stdout);
1624 perf_event__fprintf(event, stdout); 1741 perf_event__fprintf(event, stdout);
1625 ret = 0; 1742 ret = 0;
1626out: 1743out:
@@ -1655,7 +1772,7 @@ static int process_namespaces_event(struct perf_tool *tool,
1655 sample->tid = event->namespaces.tid; 1772 sample->tid = event->namespaces.tid;
1656 sample->pid = event->namespaces.pid; 1773 sample->pid = event->namespaces.pid;
1657 } 1774 }
1658 print_sample_start(sample, thread, evsel); 1775 perf_sample__fprintf_start(sample, thread, evsel, stdout);
1659 perf_event__fprintf(event, stdout); 1776 perf_event__fprintf(event, stdout);
1660 ret = 0; 1777 ret = 0;
1661out: 1778out:
@@ -1688,7 +1805,7 @@ static int process_fork_event(struct perf_tool *tool,
1688 sample->tid = event->fork.tid; 1805 sample->tid = event->fork.tid;
1689 sample->pid = event->fork.pid; 1806 sample->pid = event->fork.pid;
1690 } 1807 }
1691 print_sample_start(sample, thread, evsel); 1808 perf_sample__fprintf_start(sample, thread, evsel, stdout);
1692 perf_event__fprintf(event, stdout); 1809 perf_event__fprintf(event, stdout);
1693 thread__put(thread); 1810 thread__put(thread);
1694 1811
@@ -1717,7 +1834,7 @@ static int process_exit_event(struct perf_tool *tool,
1717 sample->tid = event->fork.tid; 1834 sample->tid = event->fork.tid;
1718 sample->pid = event->fork.pid; 1835 sample->pid = event->fork.pid;
1719 } 1836 }
1720 print_sample_start(sample, thread, evsel); 1837 perf_sample__fprintf_start(sample, thread, evsel, stdout);
1721 perf_event__fprintf(event, stdout); 1838 perf_event__fprintf(event, stdout);
1722 1839
1723 if (perf_event__process_exit(tool, event, sample, machine) < 0) 1840 if (perf_event__process_exit(tool, event, sample, machine) < 0)
@@ -1752,7 +1869,7 @@ static int process_mmap_event(struct perf_tool *tool,
1752 sample->tid = event->mmap.tid; 1869 sample->tid = event->mmap.tid;
1753 sample->pid = event->mmap.pid; 1870 sample->pid = event->mmap.pid;
1754 } 1871 }
1755 print_sample_start(sample, thread, evsel); 1872 perf_sample__fprintf_start(sample, thread, evsel, stdout);
1756 perf_event__fprintf(event, stdout); 1873 perf_event__fprintf(event, stdout);
1757 thread__put(thread); 1874 thread__put(thread);
1758 return 0; 1875 return 0;
@@ -1783,7 +1900,7 @@ static int process_mmap2_event(struct perf_tool *tool,
1783 sample->tid = event->mmap2.tid; 1900 sample->tid = event->mmap2.tid;
1784 sample->pid = event->mmap2.pid; 1901 sample->pid = event->mmap2.pid;
1785 } 1902 }
1786 print_sample_start(sample, thread, evsel); 1903 perf_sample__fprintf_start(sample, thread, evsel, stdout);
1787 perf_event__fprintf(event, stdout); 1904 perf_event__fprintf(event, stdout);
1788 thread__put(thread); 1905 thread__put(thread);
1789 return 0; 1906 return 0;
@@ -1809,7 +1926,7 @@ static int process_switch_event(struct perf_tool *tool,
1809 return -1; 1926 return -1;
1810 } 1927 }
1811 1928
1812 print_sample_start(sample, thread, evsel); 1929 perf_sample__fprintf_start(sample, thread, evsel, stdout);
1813 perf_event__fprintf(event, stdout); 1930 perf_event__fprintf(event, stdout);
1814 thread__put(thread); 1931 thread__put(thread);
1815 return 0; 1932 return 0;
@@ -1820,6 +1937,65 @@ static void sig_handler(int sig __maybe_unused)
1820 session_done = 1; 1937 session_done = 1;
1821} 1938}
1822 1939
1940static void perf_script__fclose_per_event_dump(struct perf_script *script)
1941{
1942 struct perf_evlist *evlist = script->session->evlist;
1943 struct perf_evsel *evsel;
1944
1945 evlist__for_each_entry(evlist, evsel) {
1946 if (!evsel->priv)
1947 break;
1948 perf_evsel_script__delete(evsel->priv);
1949 evsel->priv = NULL;
1950 }
1951}
1952
1953static int perf_script__fopen_per_event_dump(struct perf_script *script)
1954{
1955 struct perf_evsel *evsel;
1956
1957 evlist__for_each_entry(script->session->evlist, evsel) {
1958 evsel->priv = perf_evsel_script__new(evsel, script->session->data);
1959 if (evsel->priv == NULL)
1960 goto out_err_fclose;
1961 }
1962
1963 return 0;
1964
1965out_err_fclose:
1966 perf_script__fclose_per_event_dump(script);
1967 return -1;
1968}
1969
1970static int perf_script__setup_per_event_dump(struct perf_script *script)
1971{
1972 struct perf_evsel *evsel;
1973 static struct perf_evsel_script es_stdout;
1974
1975 if (script->per_event_dump)
1976 return perf_script__fopen_per_event_dump(script);
1977
1978 es_stdout.fp = stdout;
1979
1980 evlist__for_each_entry(script->session->evlist, evsel)
1981 evsel->priv = &es_stdout;
1982
1983 return 0;
1984}
1985
1986static void perf_script__exit_per_event_dump_stats(struct perf_script *script)
1987{
1988 struct perf_evsel *evsel;
1989
1990 evlist__for_each_entry(script->session->evlist, evsel) {
1991 struct perf_evsel_script *es = evsel->priv;
1992
1993 perf_evsel_script__fprintf(es, stdout);
1994 perf_evsel_script__delete(es);
1995 evsel->priv = NULL;
1996 }
1997}
1998
1823static int __cmd_script(struct perf_script *script) 1999static int __cmd_script(struct perf_script *script)
1824{ 2000{
1825 int ret; 2001 int ret;
@@ -1841,8 +2017,16 @@ static int __cmd_script(struct perf_script *script)
1841 if (script->show_namespace_events) 2017 if (script->show_namespace_events)
1842 script->tool.namespaces = process_namespaces_event; 2018 script->tool.namespaces = process_namespaces_event;
1843 2019
2020 if (perf_script__setup_per_event_dump(script)) {
2021 pr_err("Couldn't create the per event dump files\n");
2022 return -1;
2023 }
2024
1844 ret = perf_session__process_events(script->session); 2025 ret = perf_session__process_events(script->session);
1845 2026
2027 if (script->per_event_dump)
2028 perf_script__exit_per_event_dump_stats(script);
2029
1846 if (debug_mode) 2030 if (debug_mode)
1847 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 2031 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
1848 2032
@@ -2199,16 +2383,11 @@ static struct script_desc *script_desc__findnew(const char *name)
2199 2383
2200 s = script_desc__new(name); 2384 s = script_desc__new(name);
2201 if (!s) 2385 if (!s)
2202 goto out_delete_desc; 2386 return NULL;
2203 2387
2204 script_desc__add(s); 2388 script_desc__add(s);
2205 2389
2206 return s; 2390 return s;
2207
2208out_delete_desc:
2209 script_desc__delete(s);
2210
2211 return NULL;
2212} 2391}
2213 2392
2214static const char *ends_with(const char *str, const char *suffix) 2393static const char *ends_with(const char *str, const char *suffix)
@@ -2412,14 +2591,16 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
2412 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; 2591 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
2413 DIR *scripts_dir, *lang_dir; 2592 DIR *scripts_dir, *lang_dir;
2414 struct perf_session *session; 2593 struct perf_session *session;
2415 struct perf_data_file file = { 2594 struct perf_data data = {
2416 .path = input_name, 2595 .file = {
2417 .mode = PERF_DATA_MODE_READ, 2596 .path = input_name,
2597 },
2598 .mode = PERF_DATA_MODE_READ,
2418 }; 2599 };
2419 char *temp; 2600 char *temp;
2420 int i = 0; 2601 int i = 0;
2421 2602
2422 session = perf_session__new(&file, false, NULL); 2603 session = perf_session__new(&data, false, NULL);
2423 if (!session) 2604 if (!session)
2424 return -1; 2605 return -1;
2425 2606
@@ -2682,6 +2863,7 @@ int cmd_script(int argc, const char **argv)
2682 .attr = process_attr, 2863 .attr = process_attr,
2683 .event_update = perf_event__process_event_update, 2864 .event_update = perf_event__process_event_update,
2684 .tracing_data = perf_event__process_tracing_data, 2865 .tracing_data = perf_event__process_tracing_data,
2866 .feature = perf_event__process_feature,
2685 .build_id = perf_event__process_build_id, 2867 .build_id = perf_event__process_build_id,
2686 .id_index = perf_event__process_id_index, 2868 .id_index = perf_event__process_id_index,
2687 .auxtrace_info = perf_event__process_auxtrace_info, 2869 .auxtrace_info = perf_event__process_auxtrace_info,
@@ -2696,7 +2878,7 @@ int cmd_script(int argc, const char **argv)
2696 .ordering_requires_timestamps = true, 2878 .ordering_requires_timestamps = true,
2697 }, 2879 },
2698 }; 2880 };
2699 struct perf_data_file file = { 2881 struct perf_data data = {
2700 .mode = PERF_DATA_MODE_READ, 2882 .mode = PERF_DATA_MODE_READ,
2701 }; 2883 };
2702 const struct option options[] = { 2884 const struct option options[] = {
@@ -2732,8 +2914,8 @@ int cmd_script(int argc, const char **argv)
2732 "+field to add and -field to remove." 2914 "+field to add and -field to remove."
2733 "Valid types: hw,sw,trace,raw,synth. " 2915 "Valid types: hw,sw,trace,raw,synth. "
2734 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 2916 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
2735 "addr,symoff,period,iregs,brstack,brstacksym,flags," 2917 "addr,symoff,period,iregs,uregs,brstack,brstacksym,flags,"
2736 "bpf-output,callindent,insn,insnlen,brstackinsn,synth", 2918 "bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr",
2737 parse_output_fields), 2919 parse_output_fields),
2738 OPT_BOOLEAN('a', "all-cpus", &system_wide, 2920 OPT_BOOLEAN('a', "all-cpus", &system_wide,
2739 "system-wide collection from all CPUs"), 2921 "system-wide collection from all CPUs"),
@@ -2764,6 +2946,8 @@ int cmd_script(int argc, const char **argv)
2764 "Show context switch events (if recorded)"), 2946 "Show context switch events (if recorded)"),
2765 OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events, 2947 OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
2766 "Show namespace events (if recorded)"), 2948 "Show namespace events (if recorded)"),
2949 OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
2950 "Dump trace output to files named by the monitored events"),
2767 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), 2951 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
2768 OPT_INTEGER(0, "max-blocks", &max_blocks, 2952 OPT_INTEGER(0, "max-blocks", &max_blocks,
2769 "Maximum number of code blocks to dump with brstackinsn"), 2953 "Maximum number of code blocks to dump with brstackinsn"),
@@ -2794,13 +2978,15 @@ int cmd_script(int argc, const char **argv)
2794 NULL 2978 NULL
2795 }; 2979 };
2796 2980
2981 perf_set_singlethreaded();
2982
2797 setup_scripting(); 2983 setup_scripting();
2798 2984
2799 argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage, 2985 argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
2800 PARSE_OPT_STOP_AT_NON_OPTION); 2986 PARSE_OPT_STOP_AT_NON_OPTION);
2801 2987
2802 file.path = input_name; 2988 data.file.path = input_name;
2803 file.force = symbol_conf.force; 2989 data.force = symbol_conf.force;
2804 2990
2805 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { 2991 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
2806 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); 2992 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
@@ -2967,15 +3153,18 @@ int cmd_script(int argc, const char **argv)
2967 if (!script_name) 3153 if (!script_name)
2968 setup_pager(); 3154 setup_pager();
2969 3155
2970 session = perf_session__new(&file, false, &script.tool); 3156 session = perf_session__new(&data, false, &script.tool);
2971 if (session == NULL) 3157 if (session == NULL)
2972 return -1; 3158 return -1;
2973 3159
2974 if (header || header_only) { 3160 if (header || header_only) {
3161 script.tool.show_feat_hdr = SHOW_FEAT_HEADER;
2975 perf_session__fprintf_info(session, stdout, show_full_info); 3162 perf_session__fprintf_info(session, stdout, show_full_info);
2976 if (header_only) 3163 if (header_only)
2977 goto out_delete; 3164 goto out_delete;
2978 } 3165 }
3166 if (show_full_info)
3167 script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
2979 3168
2980 if (symbol__init(&session->header.env) < 0) 3169 if (symbol__init(&session->header.env) < 0)
2981 goto out_delete; 3170 goto out_delete;
@@ -3005,7 +3194,8 @@ int cmd_script(int argc, const char **argv)
3005 machine__resolve_kernel_addr, 3194 machine__resolve_kernel_addr,
3006 &session->machines.host) < 0) { 3195 &session->machines.host) < 0) {
3007 pr_err("%s: failed to set libtraceevent function resolver\n", __func__); 3196 pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
3008 return -1; 3197 err = -1;
3198 goto out_delete;
3009 } 3199 }
3010 3200
3011 if (generate_script_lang) { 3201 if (generate_script_lang) {
@@ -3019,7 +3209,7 @@ int cmd_script(int argc, const char **argv)
3019 goto out_delete; 3209 goto out_delete;
3020 } 3210 }
3021 3211
3022 input = open(file.path, O_RDONLY); /* input_name */ 3212 input = open(data.file.path, O_RDONLY); /* input_name */
3023 if (input < 0) { 3213 if (input < 0) {
3024 err = -errno; 3214 err = -errno;
3025 perror("failed to open file"); 3215 perror("failed to open file");
@@ -3065,7 +3255,8 @@ int cmd_script(int argc, const char **argv)
3065 /* needs to be parsed after looking up reference time */ 3255 /* needs to be parsed after looking up reference time */
3066 if (perf_time__parse_str(&script.ptime, script.time_str) != 0) { 3256 if (perf_time__parse_str(&script.ptime, script.time_str) != 0) {
3067 pr_err("Invalid time string\n"); 3257 pr_err("Invalid time string\n");
3068 return -EINVAL; 3258 err = -EINVAL;
3259 goto out_delete;
3069 } 3260 }
3070 3261
3071 err = __cmd_script(&script); 3262 err = __cmd_script(&script);