diff options
author | Namhyung Kim <namhyung.kim@lge.com> | 2012-06-26 20:41:41 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-06-29 12:28:12 -0400 |
commit | e080e6f1c863242ff709046d0486d09c46dc484a (patch) | |
tree | 0b5235ad5fcd1b2bf2c4fe326f0c212c3554f787 /tools/lib | |
parent | b700807196ac8d87e00fed9fda80ab89b7f56db6 (diff) |
tools lib traceevent: Add support for __print_hex()
Since the __print_hex() function is used in print fmt now, add
corresponding parser routines. This makes the output of perf script on
the kvm_emulate_insn event not to fail any more.
before:
kvm_emulate_insn: [FAILED TO PARSE] rip=3238197797 ...
after:
kvm_emulate_insn: 0:c102fa25:89 10 (prot32)
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/1340757701-10711-4-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/lib')
-rw-r--r-- | tools/lib/traceevent/event-parse.c | 75 | ||||
-rw-r--r-- | tools/lib/traceevent/event-parse.h | 7 |
2 files changed, 81 insertions, 1 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 63d02be5480f..b1abd39923d6 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -697,6 +697,10 @@ static void free_arg(struct print_arg *arg) | |||
697 | free_arg(arg->symbol.field); | 697 | free_arg(arg->symbol.field); |
698 | free_flag_sym(arg->symbol.symbols); | 698 | free_flag_sym(arg->symbol.symbols); |
699 | break; | 699 | break; |
700 | case PRINT_HEX: | ||
701 | free_arg(arg->hex.field); | ||
702 | free_arg(arg->hex.size); | ||
703 | break; | ||
700 | case PRINT_TYPE: | 704 | case PRINT_TYPE: |
701 | free(arg->typecast.type); | 705 | free(arg->typecast.type); |
702 | free_arg(arg->typecast.item); | 706 | free_arg(arg->typecast.item); |
@@ -2260,6 +2264,45 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok) | |||
2260 | } | 2264 | } |
2261 | 2265 | ||
2262 | static enum event_type | 2266 | static enum event_type |
2267 | process_hex(struct event_format *event, struct print_arg *arg, char **tok) | ||
2268 | { | ||
2269 | struct print_arg *field; | ||
2270 | enum event_type type; | ||
2271 | char *token; | ||
2272 | |||
2273 | memset(arg, 0, sizeof(*arg)); | ||
2274 | arg->type = PRINT_HEX; | ||
2275 | |||
2276 | field = alloc_arg(); | ||
2277 | type = process_arg(event, field, &token); | ||
2278 | |||
2279 | if (test_type_token(type, token, EVENT_DELIM, ",")) | ||
2280 | goto out_free; | ||
2281 | |||
2282 | arg->hex.field = field; | ||
2283 | |||
2284 | free_token(token); | ||
2285 | |||
2286 | field = alloc_arg(); | ||
2287 | type = process_arg(event, field, &token); | ||
2288 | |||
2289 | if (test_type_token(type, token, EVENT_DELIM, ")")) | ||
2290 | goto out_free; | ||
2291 | |||
2292 | arg->hex.size = field; | ||
2293 | |||
2294 | free_token(token); | ||
2295 | type = read_token_item(tok); | ||
2296 | return type; | ||
2297 | |||
2298 | out_free: | ||
2299 | free_arg(field); | ||
2300 | free_token(token); | ||
2301 | *tok = NULL; | ||
2302 | return EVENT_ERROR; | ||
2303 | } | ||
2304 | |||
2305 | static enum event_type | ||
2263 | process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) | 2306 | process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) |
2264 | { | 2307 | { |
2265 | struct format_field *field; | 2308 | struct format_field *field; |
@@ -2488,6 +2531,10 @@ process_function(struct event_format *event, struct print_arg *arg, | |||
2488 | is_symbolic_field = 1; | 2531 | is_symbolic_field = 1; |
2489 | return process_symbols(event, arg, tok); | 2532 | return process_symbols(event, arg, tok); |
2490 | } | 2533 | } |
2534 | if (strcmp(token, "__print_hex") == 0) { | ||
2535 | free_token(token); | ||
2536 | return process_hex(event, arg, tok); | ||
2537 | } | ||
2491 | if (strcmp(token, "__get_str") == 0) { | 2538 | if (strcmp(token, "__get_str") == 0) { |
2492 | free_token(token); | 2539 | free_token(token); |
2493 | return process_str(event, arg, tok); | 2540 | return process_str(event, arg, tok); |
@@ -2995,6 +3042,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg | |||
2995 | break; | 3042 | break; |
2996 | case PRINT_FLAGS: | 3043 | case PRINT_FLAGS: |
2997 | case PRINT_SYMBOL: | 3044 | case PRINT_SYMBOL: |
3045 | case PRINT_HEX: | ||
2998 | break; | 3046 | break; |
2999 | case PRINT_TYPE: | 3047 | case PRINT_TYPE: |
3000 | val = eval_num_arg(data, size, event, arg->typecast.item); | 3048 | val = eval_num_arg(data, size, event, arg->typecast.item); |
@@ -3218,8 +3266,9 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
3218 | unsigned long long val, fval; | 3266 | unsigned long long val, fval; |
3219 | unsigned long addr; | 3267 | unsigned long addr; |
3220 | char *str; | 3268 | char *str; |
3269 | unsigned char *hex; | ||
3221 | int print; | 3270 | int print; |
3222 | int len; | 3271 | int i, len; |
3223 | 3272 | ||
3224 | switch (arg->type) { | 3273 | switch (arg->type) { |
3225 | case PRINT_NULL: | 3274 | case PRINT_NULL: |
@@ -3284,6 +3333,23 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
3284 | } | 3333 | } |
3285 | } | 3334 | } |
3286 | break; | 3335 | break; |
3336 | case PRINT_HEX: | ||
3337 | field = arg->hex.field->field.field; | ||
3338 | if (!field) { | ||
3339 | str = arg->hex.field->field.name; | ||
3340 | field = pevent_find_any_field(event, str); | ||
3341 | if (!field) | ||
3342 | die("field %s not found", str); | ||
3343 | arg->hex.field->field.field = field; | ||
3344 | } | ||
3345 | hex = data + field->offset; | ||
3346 | len = eval_num_arg(data, size, event, arg->hex.size); | ||
3347 | for (i = 0; i < len; i++) { | ||
3348 | if (i) | ||
3349 | trace_seq_putc(s, ' '); | ||
3350 | trace_seq_printf(s, "%02x", hex[i]); | ||
3351 | } | ||
3352 | break; | ||
3287 | 3353 | ||
3288 | case PRINT_TYPE: | 3354 | case PRINT_TYPE: |
3289 | break; | 3355 | break; |
@@ -4294,6 +4360,13 @@ static void print_args(struct print_arg *args) | |||
4294 | trace_seq_destroy(&s); | 4360 | trace_seq_destroy(&s); |
4295 | printf(")"); | 4361 | printf(")"); |
4296 | break; | 4362 | break; |
4363 | case PRINT_HEX: | ||
4364 | printf("__print_hex("); | ||
4365 | print_args(args->hex.field); | ||
4366 | printf(", "); | ||
4367 | print_args(args->hex.size); | ||
4368 | printf(")"); | ||
4369 | break; | ||
4297 | case PRINT_STRING: | 4370 | case PRINT_STRING: |
4298 | case PRINT_BSTRING: | 4371 | case PRINT_BSTRING: |
4299 | printf("__get_str(%s)", args->string.string); | 4372 | printf("__get_str(%s)", args->string.string); |
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index ac997bc7b592..5772ad8cb386 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
@@ -226,6 +226,11 @@ struct print_arg_symbol { | |||
226 | struct print_flag_sym *symbols; | 226 | struct print_flag_sym *symbols; |
227 | }; | 227 | }; |
228 | 228 | ||
229 | struct print_arg_hex { | ||
230 | struct print_arg *field; | ||
231 | struct print_arg *size; | ||
232 | }; | ||
233 | |||
229 | struct print_arg_dynarray { | 234 | struct print_arg_dynarray { |
230 | struct format_field *field; | 235 | struct format_field *field; |
231 | struct print_arg *index; | 236 | struct print_arg *index; |
@@ -253,6 +258,7 @@ enum print_arg_type { | |||
253 | PRINT_FIELD, | 258 | PRINT_FIELD, |
254 | PRINT_FLAGS, | 259 | PRINT_FLAGS, |
255 | PRINT_SYMBOL, | 260 | PRINT_SYMBOL, |
261 | PRINT_HEX, | ||
256 | PRINT_TYPE, | 262 | PRINT_TYPE, |
257 | PRINT_STRING, | 263 | PRINT_STRING, |
258 | PRINT_BSTRING, | 264 | PRINT_BSTRING, |
@@ -270,6 +276,7 @@ struct print_arg { | |||
270 | struct print_arg_typecast typecast; | 276 | struct print_arg_typecast typecast; |
271 | struct print_arg_flags flags; | 277 | struct print_arg_flags flags; |
272 | struct print_arg_symbol symbol; | 278 | struct print_arg_symbol symbol; |
279 | struct print_arg_hex hex; | ||
273 | struct print_arg_func func; | 280 | struct print_arg_func func; |
274 | struct print_arg_string string; | 281 | struct print_arg_string string; |
275 | struct print_arg_op op; | 282 | struct print_arg_op op; |