diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-11-23 21:46:35 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2009-11-23 21:46:35 -0500 |
commit | 4a8ad9041eaaf8019b0488dc598efe38d07a5220 (patch) | |
tree | ade3cacadc1c85778d230955fe55762643f2ed5a | |
parent | 28c86bb67da8dc23c109f13cbf2ade4dbbda5ac8 (diff) |
Add handling of __get_dynamic_array
This adds some code to handle direct uses of __dynamic_array.
It still needs to handle the type casting for it.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | parse-events.c | 103 | ||||
-rw-r--r-- | parse-events.h | 7 |
2 files changed, 100 insertions, 10 deletions
diff --git a/parse-events.c b/parse-events.c index 6478efc..e7e2fc0 100644 --- a/parse-events.c +++ b/parse-events.c | |||
@@ -49,6 +49,8 @@ static unsigned long long input_buf_siz; | |||
49 | static int cpus; | 49 | static int cpus; |
50 | static int long_size; | 50 | static int long_size; |
51 | 51 | ||
52 | static struct format_field *find_field(struct event *event, const char *name); | ||
53 | |||
52 | static void init_input_buf(char *buf, unsigned long long size) | 54 | static void init_input_buf(char *buf, unsigned long long size) |
53 | { | 55 | { |
54 | input_buf = buf; | 56 | input_buf = buf; |
@@ -1593,6 +1595,63 @@ out_free: | |||
1593 | } | 1595 | } |
1594 | 1596 | ||
1595 | static enum event_type | 1597 | static enum event_type |
1598 | process_dynamic_array(struct event *event, struct print_arg *arg, char **tok) | ||
1599 | { | ||
1600 | struct format_field *field; | ||
1601 | enum event_type type; | ||
1602 | char *token; | ||
1603 | |||
1604 | memset(arg, 0, sizeof(*arg)); | ||
1605 | arg->type = PRINT_DYNAMIC_ARRAY; | ||
1606 | |||
1607 | if (read_expected_item(EVENT_DELIM, "(") < 0) | ||
1608 | return EVENT_ERROR; | ||
1609 | |||
1610 | /* | ||
1611 | * The item within the parenthesis is another field that holds | ||
1612 | * the index into where the array starts. | ||
1613 | */ | ||
1614 | type = read_token(&token); | ||
1615 | *tok = token; | ||
1616 | if (type != EVENT_ITEM) | ||
1617 | return EVENT_ERROR; | ||
1618 | |||
1619 | /* Find the field */ | ||
1620 | |||
1621 | field = find_field(event, token); | ||
1622 | if (!field) | ||
1623 | return EVENT_ERROR; | ||
1624 | |||
1625 | arg->dynarray.field = field; | ||
1626 | arg->dynarray.index = 0; | ||
1627 | |||
1628 | if (read_expected(EVENT_DELIM, ")") < 0) | ||
1629 | return EVENT_ERROR; | ||
1630 | |||
1631 | type = read_token_item(&token); | ||
1632 | *tok = token; | ||
1633 | if (type != EVENT_OP || strcmp(token, "[") != 0) | ||
1634 | return type; | ||
1635 | |||
1636 | free_token(token); | ||
1637 | arg = malloc_or_die(sizeof(*arg)); | ||
1638 | type = process_arg(event, arg, &token); | ||
1639 | if (type == EVENT_ERROR) | ||
1640 | goto out_free; | ||
1641 | |||
1642 | if (!test_type_token(type, token, EVENT_OP, "]")) | ||
1643 | goto out_free; | ||
1644 | |||
1645 | free_token(token); | ||
1646 | type = read_token_item(tok); | ||
1647 | return type; | ||
1648 | |||
1649 | out_free: | ||
1650 | free(arg); | ||
1651 | return EVENT_ERROR; | ||
1652 | } | ||
1653 | |||
1654 | static enum event_type | ||
1596 | process_paren(struct event *event, struct print_arg *arg, char **tok) | 1655 | process_paren(struct event *event, struct print_arg *arg, char **tok) |
1597 | { | 1656 | { |
1598 | struct print_arg *item_arg; | 1657 | struct print_arg *item_arg; |
@@ -1696,6 +1755,9 @@ process_arg_token(struct event *event, struct print_arg *arg, | |||
1696 | } else if (strcmp(token, "__get_str") == 0) { | 1755 | } else if (strcmp(token, "__get_str") == 0) { |
1697 | free_token(token); | 1756 | free_token(token); |
1698 | type = process_str(event, arg, &token); | 1757 | type = process_str(event, arg, &token); |
1758 | } else if (strcmp(token, "__get_dynamic_array") == 0) { | ||
1759 | free_token(token); | ||
1760 | type = process_dynamic_array(event, arg, &token); | ||
1699 | } else { | 1761 | } else { |
1700 | atom = token; | 1762 | atom = token; |
1701 | /* test the next token */ | 1763 | /* test the next token */ |
@@ -2014,6 +2076,8 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
2014 | unsigned long long val = 0; | 2076 | unsigned long long val = 0; |
2015 | unsigned long long left, right; | 2077 | unsigned long long left, right; |
2016 | struct print_arg *larg; | 2078 | struct print_arg *larg; |
2079 | unsigned long offset; | ||
2080 | int len; | ||
2017 | 2081 | ||
2018 | switch (arg->type) { | 2082 | switch (arg->type) { |
2019 | case PRINT_NULL: | 2083 | case PRINT_NULL: |
@@ -2045,18 +2109,37 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
2045 | * Arrays are special, since we don't want | 2109 | * Arrays are special, since we don't want |
2046 | * to read the arg as is. | 2110 | * to read the arg as is. |
2047 | */ | 2111 | */ |
2048 | if (arg->op.left->type != PRINT_FIELD) | 2112 | right = eval_num_arg(data, size, event, arg->op.right); |
2113 | switch (arg->op.left->type) { | ||
2114 | case PRINT_DYNAMIC_ARRAY: | ||
2115 | breakpoint(); | ||
2116 | larg = arg->op.left; | ||
2117 | offset = read_size(data + larg->dynarray.field->offset, | ||
2118 | larg->dynarray.field->size); | ||
2119 | /* | ||
2120 | * The actual length of the dynamic array is stored | ||
2121 | * in the top half of the field, and the offset | ||
2122 | * is in the bottom half of the 32 bit field. | ||
2123 | */ | ||
2124 | offset &= 0xffff; | ||
2125 | offset += right; | ||
2126 | len = 1; | ||
2127 | break; | ||
2128 | case PRINT_FIELD: | ||
2129 | larg = arg->op.left; | ||
2130 | if (!larg->field.field) { | ||
2131 | larg->field.field = | ||
2132 | find_any_field(event, larg->field.name); | ||
2133 | if (!larg->field.field) | ||
2134 | die("field %s not found", larg->field.name); | ||
2135 | } | ||
2136 | offset = larg->field.field->offset + | ||
2137 | right * long_size; | ||
2138 | len = long_size; | ||
2139 | default: | ||
2049 | goto default_op; /* oops, all bets off */ | 2140 | goto default_op; /* oops, all bets off */ |
2050 | larg = arg->op.left; | ||
2051 | if (!larg->field.field) { | ||
2052 | larg->field.field = | ||
2053 | find_any_field(event, larg->field.name); | ||
2054 | if (!larg->field.field) | ||
2055 | die("field %s not found", larg->field.name); | ||
2056 | } | 2141 | } |
2057 | right = eval_num_arg(data, size, event, arg->op.right); | 2142 | val = read_size(data + offset, len); |
2058 | val = read_size(data + larg->field.field->offset + | ||
2059 | right * long_size, long_size); | ||
2060 | break; | 2143 | break; |
2061 | } | 2144 | } |
2062 | default_op: | 2145 | default_op: |
diff --git a/parse-events.h b/parse-events.h index 4858a52..beee837 100644 --- a/parse-events.h +++ b/parse-events.h | |||
@@ -88,6 +88,11 @@ struct print_arg_symbol { | |||
88 | struct print_flag_sym *symbols; | 88 | struct print_flag_sym *symbols; |
89 | }; | 89 | }; |
90 | 90 | ||
91 | struct print_arg_dynarray { | ||
92 | struct format_field *field; | ||
93 | struct print_arg *index; | ||
94 | }; | ||
95 | |||
91 | struct print_arg; | 96 | struct print_arg; |
92 | 97 | ||
93 | struct print_arg_op { | 98 | struct print_arg_op { |
@@ -110,6 +115,7 @@ enum print_arg_type { | |||
110 | PRINT_SYMBOL, | 115 | PRINT_SYMBOL, |
111 | PRINT_TYPE, | 116 | PRINT_TYPE, |
112 | PRINT_STRING, | 117 | PRINT_STRING, |
118 | PRINT_DYNAMIC_ARRAY, | ||
113 | PRINT_OP, | 119 | PRINT_OP, |
114 | }; | 120 | }; |
115 | 121 | ||
@@ -125,6 +131,7 @@ struct print_arg { | |||
125 | struct print_arg_func func; | 131 | struct print_arg_func func; |
126 | struct print_arg_string string; | 132 | struct print_arg_string string; |
127 | struct print_arg_op op; | 133 | struct print_arg_op op; |
134 | struct print_arg_dynarray dynarray; | ||
128 | }; | 135 | }; |
129 | }; | 136 | }; |
130 | 137 | ||