aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--trace-cmd.h3
-rw-r--r--trace-input.c113
2 files changed, 86 insertions, 30 deletions
diff --git a/trace-cmd.h b/trace-cmd.h
index be38ef2..0ebed96 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -53,6 +53,9 @@ tracecmd_read_data(struct tracecmd_handle *handle, int cpu);
53struct record * 53struct record *
54tracecmd_read_at(struct tracecmd_handle *handle, unsigned long long offset, 54tracecmd_read_at(struct tracecmd_handle *handle, unsigned long long offset,
55 int *cpu); 55 int *cpu);
56struct record *
57tracecmd_translate_data(struct tracecmd_handle *handle,
58 void *ptr, int size);
56 59
57int tracecmd_ftrace_overrides(void); 60int tracecmd_ftrace_overrides(void);
58 61
diff --git a/trace-input.c b/trace-input.c
index 38dd53d..6fee129 100644
--- a/trace-input.c
+++ b/trace-input.c
@@ -700,6 +700,82 @@ tracecmd_read_at(struct tracecmd_handle *handle, unsigned long long offset,
700 return find_and_read_event(handle, offset, pcpu); 700 return find_and_read_event(handle, offset, pcpu);
701} 701}
702 702
703static unsigned int
704translate_data(void **ptr, unsigned long long *delta, int *length)
705{
706 unsigned long long extend;
707 unsigned int type_len_ts;
708 unsigned int type_len;
709
710 type_len_ts = data2host4(*ptr);
711 *ptr += 4;
712
713 type_len = type_len4host(type_len_ts);
714 *delta = ts4host(type_len_ts);
715
716 switch (type_len) {
717 case RINGBUF_TYPE_PADDING:
718 *length = data2host4(*ptr);
719 *ptr += 4;
720 *length *= 4;
721 *ptr += *length;
722 break;
723
724 case RINGBUF_TYPE_TIME_EXTEND:
725 extend = data2host4(*ptr);
726 *ptr += 4;
727 extend <<= TS_SHIFT;
728 extend += *delta;
729 *delta = extend;
730 break;
731
732 case RINGBUF_TYPE_TIME_STAMP:
733 *ptr += 12;
734 break;
735 case 0:
736 *length = data2host4(*ptr) - 4;
737 *length = (*length + 3) & ~3;
738 *ptr += 4;
739 break;
740 default:
741 *length = type_len * 4;
742 break;
743 }
744
745 return type_len;
746}
747
748struct record *
749tracecmd_translate_data(struct tracecmd_handle *handle,
750 void *ptr, int size)
751{
752 struct record *data;
753 unsigned int type_len;
754
755 /* minimum record read is 8, (warn?) (TODO: make 8 into macro) */
756 if (size < 8)
757 return NULL;
758
759 data = malloc(sizeof(*data));
760 if (!data)
761 return NULL;
762 memset(data, 0, sizeof(*data));
763
764 data->data = ptr;
765 type_len = translate_data(&data->data, &data->ts, &data->size);
766 switch (type_len) {
767 case RINGBUF_TYPE_PADDING:
768 case RINGBUF_TYPE_TIME_EXTEND:
769 case RINGBUF_TYPE_TIME_STAMP:
770 data->data = NULL;
771 break;
772 default:
773 break;
774 }
775
776 return data;
777}
778
703struct record * 779struct record *
704tracecmd_peek_data(struct tracecmd_handle *handle, int cpu) 780tracecmd_peek_data(struct tracecmd_handle *handle, int cpu)
705{ 781{
@@ -708,10 +784,8 @@ tracecmd_peek_data(struct tracecmd_handle *handle, int cpu)
708 int index = handle->cpu_data[cpu].index; 784 int index = handle->cpu_data[cpu].index;
709 void *ptr = page + index; 785 void *ptr = page + index;
710 unsigned long long extend; 786 unsigned long long extend;
711 unsigned int type_len_ts;
712 unsigned int type_len; 787 unsigned int type_len;
713 unsigned int delta; 788 int length;
714 unsigned int length;
715 789
716 /* Hack to work around function graph read ahead */ 790 /* Hack to work around function graph read ahead */
717 tracecmd_curr_thread_handle = handle; 791 tracecmd_curr_thread_handle = handle;
@@ -766,46 +840,25 @@ read_again:
766 return data; 840 return data;
767 } 841 }
768 842
769 type_len_ts = data2host4(ptr); 843 type_len = translate_data(&ptr, &extend, &length);
770 ptr += 4;
771
772 type_len = type_len4host(type_len_ts);
773 delta = ts4host(type_len_ts);
774 844
775 switch (type_len) { 845 switch (type_len) {
776 case RINGBUF_TYPE_PADDING: 846 case RINGBUF_TYPE_PADDING:
777 if (!delta) { 847 if (!extend) {
778 warning("error, hit unexpected end of page"); 848 warning("error, hit unexpected end of page");
779 return NULL; 849 return NULL;
780 } 850 }
781 length = data2host4(ptr); 851 /* fall through */
782 ptr += 4;
783 length *= 4;
784 ptr += length;
785 goto read_again;
786
787 case RINGBUF_TYPE_TIME_EXTEND: 852 case RINGBUF_TYPE_TIME_EXTEND:
788 extend = data2host4(ptr);
789 ptr += 4;
790 extend <<= TS_SHIFT;
791 extend += delta;
792 handle->cpu_data[cpu].timestamp += extend; 853 handle->cpu_data[cpu].timestamp += extend;
793 goto read_again; 854 /* fall through */
794
795 case RINGBUF_TYPE_TIME_STAMP: 855 case RINGBUF_TYPE_TIME_STAMP:
796 ptr += 12; 856 goto read_again;
797 break;
798 case 0:
799 length = data2host4(ptr) - 4;
800 length = (length + 3) & ~3;
801 ptr += 4;
802 break;
803 default: 857 default:
804 length = type_len * 4;
805 break; 858 break;
806 } 859 }
807 860
808 handle->cpu_data[cpu].timestamp += delta; 861 handle->cpu_data[cpu].timestamp += extend;
809 862
810 data = malloc(sizeof(*data)); 863 data = malloc(sizeof(*data));
811 if (!data) 864 if (!data)