diff options
author | Steven Rostedt (Google) <rostedt@goodmis.org> | 2022-12-13 23:36:45 -0500 |
---|---|---|
committer | Steven Rostedt (Google) <rostedt@goodmis.org> | 2022-12-14 08:42:22 -0500 |
commit | 2d0573af4dfda7fa739f9b4c0444f42ef03d3587 (patch) | |
tree | 2942b2518c6dcf5d42342402d811e1338e4884c2 | |
parent | 0f8a6152370582f1c1a812eca0b5f14540fef4b9 (diff) | |
download | libtraceevent-2d0573af4dfda7fa739f9b4c0444f42ef03d3587.tar.gz |
libtraceevent: Be able to handle some sizeof() calls
Parse sizeof() for known types as well as fields.
sizeof(int) is 4
sizeof(unsigned int) is 4
sizeof(long) is tep->long_size
sizeof(unsigned long) is tep->long_size
sizeof(long long) is 8
sizeof(unsigned long long) is 8
sizeof(REC->foo) is the field "foo" size value.
This will now parse the sample events of trace_events in the kernel.
Link: https://lore.kernel.org/linux-trace-devel/20221213233645.04fc15ed@gandalf.local.home
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-rw-r--r-- | src/event-parse.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/event-parse.c b/src/event-parse.c index 1aeed95..aaa06b3 100644 --- a/src/event-parse.c +++ b/src/event-parse.c @@ -3510,6 +3510,88 @@ out_free: } static enum tep_event_type +process_sizeof(struct tep_event *event, struct tep_print_arg *arg, char **tok) +{ + struct tep_format_field *field; + enum tep_event_type type; + char *token = NULL; + bool ok = false; + int ret; + + type = read_token_item(&token); + + arg->type = TEP_PRINT_ATOM; + + /* We handle some sizeof types */ + if (strcmp(token, "unsigned") == 0) { + free_token(token); + type = read_token_item(&token); + + if (type == TEP_EVENT_ERROR) + goto error; + + if (type != TEP_EVENT_ITEM) + ok = true; + } + + if (ok || strcmp(token, "int") == 0) { + arg->atom.atom = strdup("4"); + + } else if (strcmp(token, "long") == 0) { + free_token(token); + type = read_token_item(&token); + + if (token && strcmp(token, "long") == 0) { + arg->atom.atom = strdup("8"); + } else { + if (event->tep->long_size == 4) + arg->atom.atom = strdup("4"); + else + arg->atom.atom = strdup("8"); + /* The token is the next token */ + ok = true; + } + } else if (strcmp(token, "REC") == 0) { + + free_token(token); + type = read_token_item(&token); + + if (test_type_token(type, token, TEP_EVENT_OP, "->")) + goto error; + free_token(token); + + if (read_expect_type(TEP_EVENT_ITEM, &token) < 0) + goto error; + + field = tep_find_any_field(event, token); + /* Can't handle arrays (yet) */ + if (!field || field->flags & TEP_FIELD_IS_ARRAY) + goto error; + + ret = asprintf(&arg->atom.atom, "%d", field->size); + if (ret < 0) + goto error; + + } else if (!ok) { + goto error; + } + + if (!ok) { + free_token(token); + type = read_token_item(tok); + } + if (test_type_token(type, token, TEP_EVENT_DELIM, ")")) + goto error; + + free_token(token); + return read_token_item(tok); +error: + free_token(token); + *tok = NULL; + return TEP_EVENT_ERROR; +} + +static enum tep_event_type process_function(struct tep_event *event, struct tep_print_arg *arg, char *token, char **tok) { @@ -3568,6 +3650,10 @@ process_function(struct tep_event *event, struct tep_print_arg *arg, free_token(token); return process_builtin_expect(event, arg, tok); } + if (strcmp(token, "sizeof") == 0) { + free_token(token); + return process_sizeof(event, arg, tok); + } func = find_func_handler(event->tep, token); if (func) { |