diff options
| author | Javi Merino <javi.merino@arm.com> | 2015-03-24 07:07:19 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-03-24 11:46:39 -0400 |
| commit | b839e1e846edb15cff322e262e8ce412d298232e (patch) | |
| tree | 59830971a7b6e6ee2ea6432a8e63c30d5d666d1a /tools/lib | |
| parent | e1644aae4589274223c1ab9072ddbda98dd97f6a (diff) | |
tools lib traceevent: Add support for __print_array()
Since 6ea22486ba46 ("tracing: Add array printing helper") trace can
generate traces with variable element size arrays. Add support to
parse them.
Signed-off-by: Javi Merino <javi.merino@arm.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1427195239-15730-1-git-send-email-javi.merino@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/lib')
| -rw-r--r-- | tools/lib/traceevent/event-parse.c | 93 | ||||
| -rw-r--r-- | tools/lib/traceevent/event-parse.h | 8 |
2 files changed, 101 insertions, 0 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index bc227225c7f4..b6d11eea8a57 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
| @@ -766,6 +766,11 @@ static void free_arg(struct print_arg *arg) | |||
| 766 | free_arg(arg->hex.field); | 766 | free_arg(arg->hex.field); |
| 767 | free_arg(arg->hex.size); | 767 | free_arg(arg->hex.size); |
| 768 | break; | 768 | break; |
| 769 | case PRINT_INT_ARRAY: | ||
| 770 | free_arg(arg->int_array.field); | ||
| 771 | free_arg(arg->int_array.count); | ||
| 772 | free_arg(arg->int_array.el_size); | ||
| 773 | break; | ||
| 769 | case PRINT_TYPE: | 774 | case PRINT_TYPE: |
| 770 | free(arg->typecast.type); | 775 | free(arg->typecast.type); |
| 771 | free_arg(arg->typecast.item); | 776 | free_arg(arg->typecast.item); |
| @@ -2545,6 +2550,32 @@ out: | |||
| 2545 | } | 2550 | } |
| 2546 | 2551 | ||
| 2547 | static enum event_type | 2552 | static enum event_type |
| 2553 | process_int_array(struct event_format *event, struct print_arg *arg, char **tok) | ||
| 2554 | { | ||
| 2555 | memset(arg, 0, sizeof(*arg)); | ||
| 2556 | arg->type = PRINT_INT_ARRAY; | ||
| 2557 | |||
| 2558 | if (alloc_and_process_delim(event, ",", &arg->int_array.field)) | ||
| 2559 | goto out; | ||
| 2560 | |||
| 2561 | if (alloc_and_process_delim(event, ",", &arg->int_array.count)) | ||
| 2562 | goto free_field; | ||
| 2563 | |||
| 2564 | if (alloc_and_process_delim(event, ")", &arg->int_array.el_size)) | ||
| 2565 | goto free_size; | ||
| 2566 | |||
| 2567 | return read_token_item(tok); | ||
| 2568 | |||
| 2569 | free_size: | ||
| 2570 | free_arg(arg->int_array.count); | ||
| 2571 | free_field: | ||
| 2572 | free_arg(arg->int_array.field); | ||
| 2573 | out: | ||
| 2574 | *tok = NULL; | ||
| 2575 | return EVENT_ERROR; | ||
| 2576 | } | ||
| 2577 | |||
| 2578 | static enum event_type | ||
| 2548 | process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) | 2579 | process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) |
| 2549 | { | 2580 | { |
| 2550 | struct format_field *field; | 2581 | struct format_field *field; |
| @@ -2839,6 +2870,10 @@ process_function(struct event_format *event, struct print_arg *arg, | |||
| 2839 | free_token(token); | 2870 | free_token(token); |
| 2840 | return process_hex(event, arg, tok); | 2871 | return process_hex(event, arg, tok); |
| 2841 | } | 2872 | } |
| 2873 | if (strcmp(token, "__print_array") == 0) { | ||
| 2874 | free_token(token); | ||
| 2875 | return process_int_array(event, arg, tok); | ||
| 2876 | } | ||
| 2842 | if (strcmp(token, "__get_str") == 0) { | 2877 | if (strcmp(token, "__get_str") == 0) { |
| 2843 | free_token(token); | 2878 | free_token(token); |
| 2844 | return process_str(event, arg, tok); | 2879 | return process_str(event, arg, tok); |
| @@ -3367,6 +3402,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg | |||
| 3367 | break; | 3402 | break; |
| 3368 | case PRINT_FLAGS: | 3403 | case PRINT_FLAGS: |
| 3369 | case PRINT_SYMBOL: | 3404 | case PRINT_SYMBOL: |
| 3405 | case PRINT_INT_ARRAY: | ||
| 3370 | case PRINT_HEX: | 3406 | case PRINT_HEX: |
| 3371 | break; | 3407 | break; |
| 3372 | case PRINT_TYPE: | 3408 | case PRINT_TYPE: |
| @@ -3777,6 +3813,54 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
| 3777 | } | 3813 | } |
| 3778 | break; | 3814 | break; |
| 3779 | 3815 | ||
| 3816 | case PRINT_INT_ARRAY: { | ||
| 3817 | void *num; | ||
| 3818 | int el_size; | ||
| 3819 | |||
| 3820 | if (arg->int_array.field->type == PRINT_DYNAMIC_ARRAY) { | ||
| 3821 | unsigned long offset; | ||
| 3822 | struct format_field *field = | ||
| 3823 | arg->int_array.field->dynarray.field; | ||
| 3824 | offset = pevent_read_number(pevent, | ||
| 3825 | data + field->offset, | ||
| 3826 | field->size); | ||
| 3827 | num = data + (offset & 0xffff); | ||
| 3828 | } else { | ||
| 3829 | field = arg->int_array.field->field.field; | ||
| 3830 | if (!field) { | ||
| 3831 | str = arg->int_array.field->field.name; | ||
| 3832 | field = pevent_find_any_field(event, str); | ||
| 3833 | if (!field) | ||
| 3834 | goto out_warning_field; | ||
| 3835 | arg->int_array.field->field.field = field; | ||
| 3836 | } | ||
| 3837 | num = data + field->offset; | ||
| 3838 | } | ||
| 3839 | len = eval_num_arg(data, size, event, arg->int_array.count); | ||
| 3840 | el_size = eval_num_arg(data, size, event, | ||
| 3841 | arg->int_array.el_size); | ||
| 3842 | for (i = 0; i < len; i++) { | ||
| 3843 | if (i) | ||
| 3844 | trace_seq_putc(s, ' '); | ||
| 3845 | |||
| 3846 | if (el_size == 1) { | ||
| 3847 | trace_seq_printf(s, "%u", *(uint8_t *)num); | ||
| 3848 | } else if (el_size == 2) { | ||
| 3849 | trace_seq_printf(s, "%u", *(uint16_t *)num); | ||
| 3850 | } else if (el_size == 4) { | ||
| 3851 | trace_seq_printf(s, "%u", *(uint32_t *)num); | ||
| 3852 | } else if (el_size == 8) { | ||
| 3853 | trace_seq_printf(s, "%lu", *(uint64_t *)num); | ||
| 3854 | } else { | ||
| 3855 | trace_seq_printf(s, "BAD SIZE:%d 0x%x", | ||
| 3856 | el_size, *(uint8_t *)num); | ||
| 3857 | el_size = 1; | ||
| 3858 | } | ||
| 3859 | |||
| 3860 | num += el_size; | ||
| 3861 | } | ||
| 3862 | break; | ||
| 3863 | } | ||
| 3780 | case PRINT_TYPE: | 3864 | case PRINT_TYPE: |
| 3781 | break; | 3865 | break; |
| 3782 | case PRINT_STRING: { | 3866 | case PRINT_STRING: { |
| @@ -5361,6 +5445,15 @@ static void print_args(struct print_arg *args) | |||
| 5361 | print_args(args->hex.size); | 5445 | print_args(args->hex.size); |
| 5362 | printf(")"); | 5446 | printf(")"); |
| 5363 | break; | 5447 | break; |
| 5448 | case PRINT_INT_ARRAY: | ||
| 5449 | printf("__print_array("); | ||
| 5450 | print_args(args->int_array.field); | ||
| 5451 | printf(", "); | ||
| 5452 | print_args(args->int_array.count); | ||
| 5453 | printf(", "); | ||
| 5454 | print_args(args->int_array.el_size); | ||
| 5455 | printf(")"); | ||
| 5456 | break; | ||
| 5364 | case PRINT_STRING: | 5457 | case PRINT_STRING: |
| 5365 | case PRINT_BSTRING: | 5458 | case PRINT_BSTRING: |
| 5366 | printf("__get_str(%s)", args->string.string); | 5459 | printf("__get_str(%s)", args->string.string); |
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 8ca1b8ee50da..86a5839fb048 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
| @@ -251,6 +251,12 @@ struct print_arg_hex { | |||
| 251 | struct print_arg *size; | 251 | struct print_arg *size; |
| 252 | }; | 252 | }; |
| 253 | 253 | ||
| 254 | struct print_arg_int_array { | ||
| 255 | struct print_arg *field; | ||
| 256 | struct print_arg *count; | ||
| 257 | struct print_arg *el_size; | ||
| 258 | }; | ||
| 259 | |||
| 254 | struct print_arg_dynarray { | 260 | struct print_arg_dynarray { |
| 255 | struct format_field *field; | 261 | struct format_field *field; |
| 256 | struct print_arg *index; | 262 | struct print_arg *index; |
| @@ -279,6 +285,7 @@ enum print_arg_type { | |||
| 279 | PRINT_FLAGS, | 285 | PRINT_FLAGS, |
| 280 | PRINT_SYMBOL, | 286 | PRINT_SYMBOL, |
| 281 | PRINT_HEX, | 287 | PRINT_HEX, |
| 288 | PRINT_INT_ARRAY, | ||
| 282 | PRINT_TYPE, | 289 | PRINT_TYPE, |
| 283 | PRINT_STRING, | 290 | PRINT_STRING, |
| 284 | PRINT_BSTRING, | 291 | PRINT_BSTRING, |
| @@ -298,6 +305,7 @@ struct print_arg { | |||
| 298 | struct print_arg_flags flags; | 305 | struct print_arg_flags flags; |
| 299 | struct print_arg_symbol symbol; | 306 | struct print_arg_symbol symbol; |
| 300 | struct print_arg_hex hex; | 307 | struct print_arg_hex hex; |
| 308 | struct print_arg_int_array int_array; | ||
| 301 | struct print_arg_func func; | 309 | struct print_arg_func func; |
| 302 | struct print_arg_string string; | 310 | struct print_arg_string string; |
| 303 | struct print_arg_bitmask bitmask; | 311 | struct print_arg_bitmask bitmask; |
