diff options
Diffstat (limited to 'trace-input.c')
-rw-r--r-- | trace-input.c | 127 |
1 files changed, 78 insertions, 49 deletions
diff --git a/trace-input.c b/trace-input.c index ac177f0..6e35897 100644 --- a/trace-input.c +++ b/trace-input.c | |||
@@ -34,6 +34,7 @@ struct cpu_data { | |||
34 | }; | 34 | }; |
35 | 35 | ||
36 | struct tracecmd_handle { | 36 | struct tracecmd_handle { |
37 | struct pevent *pevent; | ||
37 | int fd; | 38 | int fd; |
38 | int long_size; | 39 | int long_size; |
39 | int page_size; | 40 | int page_size; |
@@ -147,26 +148,29 @@ static char *read_string(struct tracecmd_handle *handle) | |||
147 | 148 | ||
148 | static unsigned int read4(struct tracecmd_handle *handle) | 149 | static unsigned int read4(struct tracecmd_handle *handle) |
149 | { | 150 | { |
151 | struct pevent *pevent = handle->pevent; | ||
150 | unsigned int data; | 152 | unsigned int data; |
151 | 153 | ||
152 | if (do_read_check(handle, &data, 4)) | 154 | if (do_read_check(handle, &data, 4)) |
153 | return -1; | 155 | return -1; |
154 | 156 | ||
155 | return __data2host4(data); | 157 | return __data2host4(pevent, data); |
156 | } | 158 | } |
157 | 159 | ||
158 | static unsigned long long read8(struct tracecmd_handle *handle) | 160 | static unsigned long long read8(struct tracecmd_handle *handle) |
159 | { | 161 | { |
162 | struct pevent *pevent = handle->pevent; | ||
160 | unsigned long long data; | 163 | unsigned long long data; |
161 | 164 | ||
162 | if (do_read_check(handle, &data, 8)) | 165 | if (do_read_check(handle, &data, 8)) |
163 | return -1; | 166 | return -1; |
164 | 167 | ||
165 | return __data2host8(data); | 168 | return __data2host8(pevent, data); |
166 | } | 169 | } |
167 | 170 | ||
168 | static int read_header_files(struct tracecmd_handle *handle) | 171 | static int read_header_files(struct tracecmd_handle *handle) |
169 | { | 172 | { |
173 | struct pevent *pevent = handle->pevent; | ||
170 | long long size; | 174 | long long size; |
171 | char *header; | 175 | char *header; |
172 | char buf[BUFSIZ]; | 176 | char buf[BUFSIZ]; |
@@ -188,14 +192,14 @@ static int read_header_files(struct tracecmd_handle *handle) | |||
188 | if (do_read_check(handle, header, size)) | 192 | if (do_read_check(handle, header, size)) |
189 | goto failed_read; | 193 | goto failed_read; |
190 | 194 | ||
191 | pevent_parse_header_page(header, size); | 195 | pevent_parse_header_page(pevent, header, size); |
192 | free(header); | 196 | free(header); |
193 | 197 | ||
194 | /* | 198 | /* |
195 | * The size field in the page is of type long, | 199 | * The size field in the page is of type long, |
196 | * use that instead, since it represents the kernel. | 200 | * use that instead, since it represents the kernel. |
197 | */ | 201 | */ |
198 | handle->long_size = header_page_size_size; | 202 | handle->long_size = pevent->header_page_size_size; |
199 | 203 | ||
200 | if (do_read_check(handle, buf, 13)) | 204 | if (do_read_check(handle, buf, 13)) |
201 | return -1; | 205 | return -1; |
@@ -226,6 +230,7 @@ static int read_header_files(struct tracecmd_handle *handle) | |||
226 | static int read_ftrace_file(struct tracecmd_handle *handle, | 230 | static int read_ftrace_file(struct tracecmd_handle *handle, |
227 | unsigned long long size) | 231 | unsigned long long size) |
228 | { | 232 | { |
233 | struct pevent *pevent = handle->pevent; | ||
229 | char *buf; | 234 | char *buf; |
230 | 235 | ||
231 | buf = malloc(size); | 236 | buf = malloc(size); |
@@ -236,7 +241,7 @@ static int read_ftrace_file(struct tracecmd_handle *handle, | |||
236 | return -1; | 241 | return -1; |
237 | } | 242 | } |
238 | 243 | ||
239 | pevent_parse_event(buf, size, "ftrace"); | 244 | pevent_parse_event(pevent, buf, size, "ftrace"); |
240 | free(buf); | 245 | free(buf); |
241 | 246 | ||
242 | return 0; | 247 | return 0; |
@@ -245,6 +250,7 @@ static int read_ftrace_file(struct tracecmd_handle *handle, | |||
245 | static int read_event_file(struct tracecmd_handle *handle, | 250 | static int read_event_file(struct tracecmd_handle *handle, |
246 | char *system, unsigned long long size) | 251 | char *system, unsigned long long size) |
247 | { | 252 | { |
253 | struct pevent *pevent = handle->pevent; | ||
248 | char *buf; | 254 | char *buf; |
249 | 255 | ||
250 | buf = malloc(size+1); | 256 | buf = malloc(size+1); |
@@ -259,7 +265,7 @@ static int read_event_file(struct tracecmd_handle *handle, | |||
259 | buf[size] = 0; | 265 | buf[size] = 0; |
260 | if (handle->print_events) | 266 | if (handle->print_events) |
261 | printf("%s\n", buf); | 267 | printf("%s\n", buf); |
262 | pevent_parse_event(buf, size, system); | 268 | pevent_parse_event(pevent, buf, size, system); |
263 | free(buf); | 269 | free(buf); |
264 | 270 | ||
265 | return 0; | 271 | return 0; |
@@ -331,6 +337,7 @@ static int read_event_files(struct tracecmd_handle *handle) | |||
331 | 337 | ||
332 | static int read_proc_kallsyms(struct tracecmd_handle *handle) | 338 | static int read_proc_kallsyms(struct tracecmd_handle *handle) |
333 | { | 339 | { |
340 | struct pevent *pevent = handle->pevent; | ||
334 | int size; | 341 | int size; |
335 | char *buf; | 342 | char *buf; |
336 | 343 | ||
@@ -349,7 +356,7 @@ static int read_proc_kallsyms(struct tracecmd_handle *handle) | |||
349 | return -1; | 356 | return -1; |
350 | } | 357 | } |
351 | 358 | ||
352 | parse_proc_kallsyms(buf, size); | 359 | parse_proc_kallsyms(pevent, buf, size); |
353 | 360 | ||
354 | free(buf); | 361 | free(buf); |
355 | return 0; | 362 | return 0; |
@@ -384,6 +391,7 @@ static int read_ftrace_printk(struct tracecmd_handle *handle) | |||
384 | 391 | ||
385 | int tracecmd_read_headers(struct tracecmd_handle *handle) | 392 | int tracecmd_read_headers(struct tracecmd_handle *handle) |
386 | { | 393 | { |
394 | struct pevent *pevent = handle->pevent; | ||
387 | int ret; | 395 | int ret; |
388 | 396 | ||
389 | ret = read_header_files(handle); | 397 | ret = read_header_files(handle); |
@@ -407,40 +415,52 @@ int tracecmd_read_headers(struct tracecmd_handle *handle) | |||
407 | return -1; | 415 | return -1; |
408 | 416 | ||
409 | /* register default ftrace functions first */ | 417 | /* register default ftrace functions first */ |
410 | tracecmd_ftrace_overrides(); | 418 | tracecmd_ftrace_overrides(handle); |
411 | 419 | ||
412 | trace_load_plugins(); | 420 | trace_load_plugins(pevent); |
413 | 421 | ||
414 | return 0; | 422 | return 0; |
415 | } | 423 | } |
416 | 424 | ||
417 | static unsigned int type4host(unsigned int type_len_ts) | 425 | static unsigned int type4host(struct tracecmd_handle *handle, |
426 | unsigned int type_len_ts) | ||
418 | { | 427 | { |
419 | if (file_bigendian) | 428 | struct pevent *pevent = handle->pevent; |
429 | |||
430 | if (pevent->file_bigendian) | ||
420 | return (type_len_ts >> 29) & 3; | 431 | return (type_len_ts >> 29) & 3; |
421 | else | 432 | else |
422 | return type_len_ts & 3; | 433 | return type_len_ts & 3; |
423 | } | 434 | } |
424 | 435 | ||
425 | static unsigned int len4host(unsigned int type_len_ts) | 436 | static unsigned int len4host(struct tracecmd_handle *handle, |
437 | unsigned int type_len_ts) | ||
426 | { | 438 | { |
427 | if (file_bigendian) | 439 | struct pevent *pevent = handle->pevent; |
440 | |||
441 | if (pevent->file_bigendian) | ||
428 | return (type_len_ts >> 27) & 7; | 442 | return (type_len_ts >> 27) & 7; |
429 | else | 443 | else |
430 | return (type_len_ts >> 2) & 7; | 444 | return (type_len_ts >> 2) & 7; |
431 | } | 445 | } |
432 | 446 | ||
433 | static unsigned int type_len4host(unsigned int type_len_ts) | 447 | static unsigned int type_len4host(struct tracecmd_handle *handle, |
448 | unsigned int type_len_ts) | ||
434 | { | 449 | { |
435 | if (file_bigendian) | 450 | struct pevent *pevent = handle->pevent; |
451 | |||
452 | if (pevent->file_bigendian) | ||
436 | return (type_len_ts >> 27) & ((1 << 5) - 1); | 453 | return (type_len_ts >> 27) & ((1 << 5) - 1); |
437 | else | 454 | else |
438 | return type_len_ts & ((1 << 5) - 1); | 455 | return type_len_ts & ((1 << 5) - 1); |
439 | } | 456 | } |
440 | 457 | ||
441 | static unsigned int ts4host(unsigned int type_len_ts) | 458 | static unsigned int ts4host(struct tracecmd_handle *handle, |
459 | unsigned int type_len_ts) | ||
442 | { | 460 | { |
443 | if (file_bigendian) | 461 | struct pevent *pevent = handle->pevent; |
462 | |||
463 | if (pevent->file_bigendian) | ||
444 | return type_len_ts & ((1 << 27) - 1); | 464 | return type_len_ts & ((1 << 27) - 1); |
445 | else | 465 | else |
446 | return type_len_ts >> 5; | 466 | return type_len_ts >> 5; |
@@ -522,6 +542,7 @@ enum old_ring_buffer_type { | |||
522 | static struct record * | 542 | static struct record * |
523 | read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu) | 543 | read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu) |
524 | { | 544 | { |
545 | struct pevent *pevent = handle->pevent; | ||
525 | struct record *data; | 546 | struct record *data; |
526 | unsigned long long extend; | 547 | unsigned long long extend; |
527 | unsigned int type_len_ts; | 548 | unsigned int type_len_ts; |
@@ -533,12 +554,12 @@ read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu) | |||
533 | 554 | ||
534 | index = calc_index(handle, *ptr, cpu); | 555 | index = calc_index(handle, *ptr, cpu); |
535 | 556 | ||
536 | type_len_ts = data2host4(*ptr); | 557 | type_len_ts = data2host4(pevent, *ptr); |
537 | *ptr += 4; | 558 | *ptr += 4; |
538 | 559 | ||
539 | type = type4host(type_len_ts); | 560 | type = type4host(handle, type_len_ts); |
540 | len = len4host(type_len_ts); | 561 | len = len4host(handle, type_len_ts); |
541 | delta = ts4host(type_len_ts); | 562 | delta = ts4host(handle, type_len_ts); |
542 | 563 | ||
543 | switch (type) { | 564 | switch (type) { |
544 | case OLD_RINGBUF_TYPE_PADDING: | 565 | case OLD_RINGBUF_TYPE_PADDING: |
@@ -547,7 +568,7 @@ read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu) | |||
547 | return NULL; | 568 | return NULL; |
548 | 569 | ||
549 | case OLD_RINGBUF_TYPE_TIME_EXTEND: | 570 | case OLD_RINGBUF_TYPE_TIME_EXTEND: |
550 | extend = data2host4(ptr); | 571 | extend = data2host4(pevent, ptr); |
551 | extend <<= TS_SHIFT; | 572 | extend <<= TS_SHIFT; |
552 | extend += delta; | 573 | extend += delta; |
553 | handle->cpu_data[cpu].timestamp += extend; | 574 | handle->cpu_data[cpu].timestamp += extend; |
@@ -562,7 +583,7 @@ read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu) | |||
562 | if (len) | 583 | if (len) |
563 | length = len * 4; | 584 | length = len * 4; |
564 | else { | 585 | else { |
565 | length = data2host4(*ptr); | 586 | length = data2host4(pevent, *ptr); |
566 | length -= 4; | 587 | length -= 4; |
567 | *ptr += 4; | 588 | *ptr += 4; |
568 | } | 589 | } |
@@ -709,28 +730,30 @@ tracecmd_read_at(struct tracecmd_handle *handle, unsigned long long offset, | |||
709 | } | 730 | } |
710 | 731 | ||
711 | static unsigned int | 732 | static unsigned int |
712 | translate_data(void **ptr, unsigned long long *delta, int *length) | 733 | translate_data(struct tracecmd_handle *handle, |
734 | void **ptr, unsigned long long *delta, int *length) | ||
713 | { | 735 | { |
736 | struct pevent *pevent = handle->pevent; | ||
714 | unsigned long long extend; | 737 | unsigned long long extend; |
715 | unsigned int type_len_ts; | 738 | unsigned int type_len_ts; |
716 | unsigned int type_len; | 739 | unsigned int type_len; |
717 | 740 | ||
718 | type_len_ts = data2host4(*ptr); | 741 | type_len_ts = data2host4(pevent, *ptr); |
719 | *ptr += 4; | 742 | *ptr += 4; |
720 | 743 | ||
721 | type_len = type_len4host(type_len_ts); | 744 | type_len = type_len4host(handle, type_len_ts); |
722 | *delta = ts4host(type_len_ts); | 745 | *delta = ts4host(handle, type_len_ts); |
723 | 746 | ||
724 | switch (type_len) { | 747 | switch (type_len) { |
725 | case RINGBUF_TYPE_PADDING: | 748 | case RINGBUF_TYPE_PADDING: |
726 | *length = data2host4(*ptr); | 749 | *length = data2host4(pevent, *ptr); |
727 | *ptr += 4; | 750 | *ptr += 4; |
728 | *length *= 4; | 751 | *length *= 4; |
729 | *ptr += *length; | 752 | *ptr += *length; |
730 | break; | 753 | break; |
731 | 754 | ||
732 | case RINGBUF_TYPE_TIME_EXTEND: | 755 | case RINGBUF_TYPE_TIME_EXTEND: |
733 | extend = data2host4(*ptr); | 756 | extend = data2host4(pevent, *ptr); |
734 | *ptr += 4; | 757 | *ptr += 4; |
735 | extend <<= TS_SHIFT; | 758 | extend <<= TS_SHIFT; |
736 | extend += *delta; | 759 | extend += *delta; |
@@ -741,7 +764,7 @@ translate_data(void **ptr, unsigned long long *delta, int *length) | |||
741 | *ptr += 12; | 764 | *ptr += 12; |
742 | break; | 765 | break; |
743 | case 0: | 766 | case 0: |
744 | *length = data2host4(*ptr) - 4; | 767 | *length = data2host4(pevent, *ptr) - 4; |
745 | *length = (*length + 3) & ~3; | 768 | *length = (*length + 3) & ~3; |
746 | *ptr += 4; | 769 | *ptr += 4; |
747 | break; | 770 | break; |
@@ -770,7 +793,7 @@ tracecmd_translate_data(struct tracecmd_handle *handle, | |||
770 | memset(data, 0, sizeof(*data)); | 793 | memset(data, 0, sizeof(*data)); |
771 | 794 | ||
772 | data->data = ptr; | 795 | data->data = ptr; |
773 | type_len = translate_data(&data->data, &data->ts, &data->size); | 796 | type_len = translate_data(handle, &data->data, &data->ts, &data->size); |
774 | switch (type_len) { | 797 | switch (type_len) { |
775 | case RINGBUF_TYPE_PADDING: | 798 | case RINGBUF_TYPE_PADDING: |
776 | case RINGBUF_TYPE_TIME_EXTEND: | 799 | case RINGBUF_TYPE_TIME_EXTEND: |
@@ -787,6 +810,7 @@ tracecmd_translate_data(struct tracecmd_handle *handle, | |||
787 | struct record * | 810 | struct record * |
788 | tracecmd_peek_data(struct tracecmd_handle *handle, int cpu) | 811 | tracecmd_peek_data(struct tracecmd_handle *handle, int cpu) |
789 | { | 812 | { |
813 | struct pevent *pevent = handle->pevent; | ||
790 | struct record *data; | 814 | struct record *data; |
791 | void *page = handle->cpu_data[cpu].page; | 815 | void *page = handle->cpu_data[cpu].page; |
792 | int index = handle->cpu_data[cpu].index; | 816 | int index = handle->cpu_data[cpu].index; |
@@ -806,26 +830,26 @@ tracecmd_peek_data(struct tracecmd_handle *handle, int cpu) | |||
806 | 830 | ||
807 | if (!index) { | 831 | if (!index) { |
808 | /* FIXME: handle header page */ | 832 | /* FIXME: handle header page */ |
809 | if (header_page_ts_size != 8) { | 833 | if (pevent->header_page_ts_size != 8) { |
810 | warning("expected a long long type for timestamp"); | 834 | warning("expected a long long type for timestamp"); |
811 | return NULL; | 835 | return NULL; |
812 | } | 836 | } |
813 | handle->cpu_data[cpu].timestamp = data2host8(ptr); | 837 | handle->cpu_data[cpu].timestamp = data2host8(pevent, ptr); |
814 | ptr += 8; | 838 | ptr += 8; |
815 | switch (header_page_size_size) { | 839 | switch (pevent->header_page_size_size) { |
816 | case 4: | 840 | case 4: |
817 | handle->cpu_data[cpu].page_size = data2host4(ptr); | 841 | handle->cpu_data[cpu].page_size = data2host4(pevent,ptr); |
818 | ptr += 4; | 842 | ptr += 4; |
819 | break; | 843 | break; |
820 | case 8: | 844 | case 8: |
821 | handle->cpu_data[cpu].page_size = data2host8(ptr); | 845 | handle->cpu_data[cpu].page_size = data2host8(pevent, ptr); |
822 | ptr += 8; | 846 | ptr += 8; |
823 | break; | 847 | break; |
824 | default: | 848 | default: |
825 | warning("bad long size"); | 849 | warning("bad long size"); |
826 | return NULL; | 850 | return NULL; |
827 | } | 851 | } |
828 | ptr = handle->cpu_data[cpu].page + header_page_data_offset; | 852 | ptr = handle->cpu_data[cpu].page + pevent->header_page_data_offset; |
829 | } | 853 | } |
830 | 854 | ||
831 | read_again: | 855 | read_again: |
@@ -837,7 +861,7 @@ read_again: | |||
837 | return tracecmd_peek_data(handle, cpu); | 861 | return tracecmd_peek_data(handle, cpu); |
838 | } | 862 | } |
839 | 863 | ||
840 | if (old_format) { | 864 | if (pevent->old_format) { |
841 | data = read_old_format(handle, &ptr, cpu); | 865 | data = read_old_format(handle, &ptr, cpu); |
842 | if (!data) { | 866 | if (!data) { |
843 | if (!ptr) | 867 | if (!ptr) |
@@ -848,7 +872,7 @@ read_again: | |||
848 | return data; | 872 | return data; |
849 | } | 873 | } |
850 | 874 | ||
851 | type_len = translate_data(&ptr, &extend, &length); | 875 | type_len = translate_data(handle, &ptr, &extend, &length); |
852 | 876 | ||
853 | switch (type_len) { | 877 | switch (type_len) { |
854 | case RINGBUF_TYPE_PADDING: | 878 | case RINGBUF_TYPE_PADDING: |
@@ -949,6 +973,7 @@ static int init_cpu(struct tracecmd_handle *handle, int cpu) | |||
949 | 973 | ||
950 | int tracecmd_init_data(struct tracecmd_handle *handle) | 974 | int tracecmd_init_data(struct tracecmd_handle *handle) |
951 | { | 975 | { |
976 | struct pevent *pevent = handle->pevent; | ||
952 | unsigned long long size; | 977 | unsigned long long size; |
953 | char *cmdlines; | 978 | char *cmdlines; |
954 | char buf[10]; | 979 | char buf[10]; |
@@ -964,14 +989,15 @@ int tracecmd_init_data(struct tracecmd_handle *handle) | |||
964 | free(cmdlines); | 989 | free(cmdlines); |
965 | return -1; | 990 | return -1; |
966 | } | 991 | } |
967 | parse_cmdlines(cmdlines, size); | 992 | parse_cmdlines(pevent, cmdlines, size); |
968 | free(cmdlines); | 993 | free(cmdlines); |
969 | 994 | ||
970 | handle->cpus = read4(handle); | 995 | handle->cpus = read4(handle); |
971 | if (handle->cpus < 0) | 996 | if (handle->cpus < 0) |
972 | return -1; | 997 | return -1; |
973 | 998 | ||
974 | parse_set_info(handle->cpus, handle->long_size); | 999 | pevent_set_cpus(pevent, handle->cpus); |
1000 | pevent_set_long_size(pevent, handle->long_size); | ||
975 | 1001 | ||
976 | /* | 1002 | /* |
977 | * Check if this is a latency report or not. | 1003 | * Check if this is a latency report or not. |
@@ -1040,14 +1066,12 @@ struct tracecmd_handle *tracecmd_open(int fd) | |||
1040 | if (do_read_check(handle, buf, 1)) | 1066 | if (do_read_check(handle, buf, 1)) |
1041 | goto failed_read; | 1067 | goto failed_read; |
1042 | 1068 | ||
1043 | /* | 1069 | handle->pevent = pevent_alloc(); |
1044 | * TODO: | 1070 | if (!handle->pevent) |
1045 | * Need to make these part of the handle. | 1071 | goto failed_read; |
1046 | * But they are currently used by parsevent. | 1072 | |
1047 | * That may need a handler too. | 1073 | handle->pevent->file_bigendian = buf[0]; |
1048 | */ | 1074 | handle->pevent->host_bigendian = bigendian(); |
1049 | file_bigendian = buf[0]; | ||
1050 | host_bigendian = bigendian(); | ||
1051 | 1075 | ||
1052 | do_read_check(handle, buf, 1); | 1076 | do_read_check(handle, buf, 1); |
1053 | handle->long_size = buf[0]; | 1077 | handle->long_size = buf[0]; |
@@ -1076,3 +1100,8 @@ int tracecmd_cpus(struct tracecmd_handle *handle) | |||
1076 | { | 1100 | { |
1077 | return handle->cpus; | 1101 | return handle->cpus; |
1078 | } | 1102 | } |
1103 | |||
1104 | struct pevent *tracecmd_get_pevent(struct tracecmd_handle *handle) | ||
1105 | { | ||
1106 | return handle->pevent; | ||
1107 | } | ||