|
68 | 68 | C(INVALID_SORT_FIELD, "Sort field must be a key or a val"), \
|
69 | 69 | C(INVALID_STR_OPERAND, "String type can not be an operand in expression"), \
|
70 | 70 | C(EXPECT_NUMBER, "Expecting numeric literal"), \
|
71 |
| - C(UNARY_MINUS_SUBEXPR, "Unary minus not supported in sub-expressions"), \ |
72 |
| - C(SYM_OFFSET_SUBEXPR, ".sym-offset not supported in sub-expressions"), |
| 71 | + C(UNARY_MINUS_SUBEXPR, "Unary minus not supported in sub-expressions"), |
73 | 72 |
|
74 | 73 | #undef C
|
75 | 74 | #define C(a, b) HIST_ERR_##a
|
@@ -1672,10 +1671,6 @@ static int contains_operator(char *str, char **sep)
|
1672 | 1671 | */
|
1673 | 1672 | minus_op = strrchr(str, '-');
|
1674 | 1673 | if (minus_op) {
|
1675 |
| - /* Unfortunately, the modifier ".sym-offset" can confuse things. */ |
1676 |
| - if (minus_op - str >= 4 && !strncmp(minus_op - 4, ".sym-offset", 11)) |
1677 |
| - goto out; |
1678 |
| - |
1679 | 1674 | /*
|
1680 | 1675 | * Unary minus is not supported in sub-expressions. If
|
1681 | 1676 | * present, it is always the next root operator.
|
@@ -2138,7 +2133,11 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
|
2138 | 2133 | *flags |= HIST_FIELD_FL_HEX;
|
2139 | 2134 | else if (strcmp(modifier, "sym") == 0)
|
2140 | 2135 | *flags |= HIST_FIELD_FL_SYM;
|
2141 |
| - else if (strcmp(modifier, "sym-offset") == 0) |
| 2136 | + /* |
| 2137 | + * 'sym-offset' occurrences in the trigger string are modified |
| 2138 | + * to 'symXoffset' to simplify arithmetic expression parsing. |
| 2139 | + */ |
| 2140 | + else if (strcmp(modifier, "symXoffset") == 0) |
2142 | 2141 | *flags |= HIST_FIELD_FL_SYM_OFFSET;
|
2143 | 2142 | else if ((strcmp(modifier, "execname") == 0) &&
|
2144 | 2143 | (strcmp(field_name, "common_pid") == 0))
|
@@ -2463,24 +2462,6 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
|
2463 | 2462 | return ERR_PTR(-EINVAL);
|
2464 | 2463 | }
|
2465 | 2464 |
|
2466 |
| - /* |
2467 |
| - * ".sym-offset" in expressions has no effect on their evaluation, |
2468 |
| - * but can confuse operator parsing. |
2469 |
| - */ |
2470 |
| - if (*n_subexprs == 0) { |
2471 |
| - sep = strstr(str, ".sym-offset"); |
2472 |
| - if (sep) { |
2473 |
| - *sep = '\0'; |
2474 |
| - if (strpbrk(str, "+-/*") || strpbrk(sep + 11, "+-/*")) { |
2475 |
| - *sep = '.'; |
2476 |
| - hist_err(file->tr, HIST_ERR_SYM_OFFSET_SUBEXPR, |
2477 |
| - errpos(sep)); |
2478 |
| - return ERR_PTR(-EINVAL); |
2479 |
| - } |
2480 |
| - *sep = '.'; |
2481 |
| - } |
2482 |
| - } |
2483 |
| - |
2484 | 2465 | field_op = contains_operator(str, &sep);
|
2485 | 2466 |
|
2486 | 2467 | if (field_op == FIELD_OP_NONE)
|
@@ -5999,7 +5980,7 @@ static int event_hist_trigger_func(struct event_command *cmd_ops,
|
5999 | 5980 | struct synth_event *se;
|
6000 | 5981 | const char *se_name;
|
6001 | 5982 | bool remove = false;
|
6002 |
| - char *trigger, *p; |
| 5983 | + char *trigger, *p, *start; |
6003 | 5984 | int ret = 0;
|
6004 | 5985 |
|
6005 | 5986 | lockdep_assert_held(&event_mutex);
|
@@ -6047,6 +6028,16 @@ static int event_hist_trigger_func(struct event_command *cmd_ops,
|
6047 | 6028 | trigger = strstrip(trigger);
|
6048 | 6029 | }
|
6049 | 6030 |
|
| 6031 | + /* |
| 6032 | + * To simplify arithmetic expression parsing, replace occurrences of |
| 6033 | + * '.sym-offset' modifier with '.symXoffset' |
| 6034 | + */ |
| 6035 | + start = strstr(trigger, ".sym-offset"); |
| 6036 | + while (start) { |
| 6037 | + *(start + 4) = 'X'; |
| 6038 | + start = strstr(start + 11, ".sym-offset"); |
| 6039 | + }; |
| 6040 | + |
6050 | 6041 | attrs = parse_hist_trigger_attrs(file->tr, trigger);
|
6051 | 6042 | if (IS_ERR(attrs))
|
6052 | 6043 | return PTR_ERR(attrs);
|
|
0 commit comments