aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (Google) <rostedt@goodmis.org>2022-12-13 23:36:45 -0500
committerSteven Rostedt (Google) <rostedt@goodmis.org>2022-12-14 08:42:22 -0500
commit2d0573af4dfda7fa739f9b4c0444f42ef03d3587 (patch)
tree2942b2518c6dcf5d42342402d811e1338e4884c2
parent0f8a6152370582f1c1a812eca0b5f14540fef4b9 (diff)
downloadlibtraceevent-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.c86
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) {