diff options
Diffstat (limited to 'trace-input.c')
| -rw-r--r-- | trace-input.c | 113 |
1 files changed, 83 insertions, 30 deletions
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 | ||
| 703 | static unsigned int | ||
| 704 | translate_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 | |||
| 748 | struct record * | ||
| 749 | tracecmd_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 | |||
| 703 | struct record * | 779 | struct record * |
| 704 | tracecmd_peek_data(struct tracecmd_handle *handle, int cpu) | 780 | tracecmd_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) |
