|
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 |
@@ -1662,10 +1661,6 @@ static int contains_operator(char *str, char **sep) |
1662 | 1661 | */ |
1663 | 1662 | minus_op = strrchr(str, '-'); |
1664 | 1663 | if (minus_op) { |
1665 | | - /* Unfortunately, the modifier ".sym-offset" can confuse things. */ |
1666 | | - if (minus_op - str >= 4 && !strncmp(minus_op - 4, ".sym-offset", 11)) |
1667 | | - goto out; |
1668 | | - |
1669 | 1664 | /* |
1670 | 1665 | * Unary minus is not supported in sub-expressions. If |
1671 | 1666 | * present, it is always the next root operator. |
@@ -2132,7 +2127,11 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, |
2132 | 2127 | *flags |= HIST_FIELD_FL_HEX; |
2133 | 2128 | else if (strcmp(modifier, "sym") == 0) |
2134 | 2129 | *flags |= HIST_FIELD_FL_SYM; |
2135 | | - else if (strcmp(modifier, "sym-offset") == 0) |
| 2130 | + /* |
| 2131 | + * 'sym-offset' occurrences in the trigger string are modified |
| 2132 | + * to 'symXoffset' to simplify arithmetic expression parsing. |
| 2133 | + */ |
| 2134 | + else if (strcmp(modifier, "symXoffset") == 0) |
2136 | 2135 | *flags |= HIST_FIELD_FL_SYM_OFFSET; |
2137 | 2136 | else if ((strcmp(modifier, "execname") == 0) && |
2138 | 2137 | (strcmp(field_name, "common_pid") == 0)) |
@@ -2457,24 +2456,6 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, |
2457 | 2456 | return ERR_PTR(-EINVAL); |
2458 | 2457 | } |
2459 | 2458 |
|
2460 | | - /* |
2461 | | - * ".sym-offset" in expressions has no effect on their evaluation, |
2462 | | - * but can confuse operator parsing. |
2463 | | - */ |
2464 | | - if (*n_subexprs == 0) { |
2465 | | - sep = strstr(str, ".sym-offset"); |
2466 | | - if (sep) { |
2467 | | - *sep = '\0'; |
2468 | | - if (strpbrk(str, "+-/*") || strpbrk(sep + 11, "+-/*")) { |
2469 | | - *sep = '.'; |
2470 | | - hist_err(file->tr, HIST_ERR_SYM_OFFSET_SUBEXPR, |
2471 | | - errpos(sep)); |
2472 | | - return ERR_PTR(-EINVAL); |
2473 | | - } |
2474 | | - *sep = '.'; |
2475 | | - } |
2476 | | - } |
2477 | | - |
2478 | 2459 | field_op = contains_operator(str, &sep); |
2479 | 2460 |
|
2480 | 2461 | if (field_op == FIELD_OP_NONE) |
@@ -5965,7 +5946,7 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, |
5965 | 5946 | struct synth_event *se; |
5966 | 5947 | const char *se_name; |
5967 | 5948 | bool remove = false; |
5968 | | - char *trigger, *p; |
| 5949 | + char *trigger, *p, *start; |
5969 | 5950 | int ret = 0; |
5970 | 5951 |
|
5971 | 5952 | lockdep_assert_held(&event_mutex); |
@@ -6013,6 +5994,16 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, |
6013 | 5994 | trigger = strstrip(trigger); |
6014 | 5995 | } |
6015 | 5996 |
|
| 5997 | + /* |
| 5998 | + * To simplify arithmetic expression parsing, replace occurrences of |
| 5999 | + * '.sym-offset' modifier with '.symXoffset' |
| 6000 | + */ |
| 6001 | + start = strstr(trigger, ".sym-offset"); |
| 6002 | + while (start) { |
| 6003 | + *(start + 4) = 'X'; |
| 6004 | + start = strstr(start + 11, ".sym-offset"); |
| 6005 | + }; |
| 6006 | + |
6016 | 6007 | attrs = parse_hist_trigger_attrs(file->tr, trigger); |
6017 | 6008 | if (IS_ERR(attrs)) |
6018 | 6009 | return PTR_ERR(attrs); |
|
0 commit comments