0001
0002
0003
0004
0005
0006 #include <stdio.h>
0007 #include <stdlib.h>
0008 #include <string.h>
0009 #include <stdarg.h>
0010 #include <errno.h>
0011 #include <sys/types.h>
0012
0013 #include "event-parse.h"
0014 #include "event-parse-local.h"
0015 #include "event-utils.h"
0016
0017 #define COMM "COMM"
0018 #define CPU "CPU"
0019
0020 static struct tep_format_field comm = {
0021 .name = "COMM",
0022 };
0023
0024 static struct tep_format_field cpu = {
0025 .name = "CPU",
0026 };
0027
0028 struct event_list {
0029 struct event_list *next;
0030 struct tep_event *event;
0031 };
0032
0033 static void show_error(char *error_buf, const char *fmt, ...)
0034 {
0035 unsigned long long index;
0036 const char *input;
0037 va_list ap;
0038 int len;
0039 int i;
0040
0041 input = get_input_buf();
0042 index = get_input_buf_ptr();
0043 len = input ? strlen(input) : 0;
0044
0045 if (len) {
0046 strcpy(error_buf, input);
0047 error_buf[len] = '\n';
0048 for (i = 1; i < len && i < index; i++)
0049 error_buf[len+i] = ' ';
0050 error_buf[len + i] = '^';
0051 error_buf[len + i + 1] = '\n';
0052 len += i+2;
0053 }
0054
0055 va_start(ap, fmt);
0056 vsnprintf(error_buf + len, TEP_FILTER_ERROR_BUFSZ - len, fmt, ap);
0057 va_end(ap);
0058 }
0059
0060 static enum tep_event_type filter_read_token(char **tok)
0061 {
0062 enum tep_event_type type;
0063 char *token = NULL;
0064
0065 do {
0066 free_token(token);
0067 type = read_token(&token);
0068 } while (type == TEP_EVENT_NEWLINE || type == TEP_EVENT_SPACE);
0069
0070
0071 if (token &&
0072 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
0073 peek_char() == '~') {
0074
0075 *tok = malloc(3);
0076 if (*tok == NULL) {
0077 free_token(token);
0078 return TEP_EVENT_ERROR;
0079 }
0080 sprintf(*tok, "%c%c", *token, '~');
0081 free_token(token);
0082
0083 read_token(&token);
0084 free_token(token);
0085 } else
0086 *tok = token;
0087
0088 return type;
0089 }
0090
0091 static int filter_cmp(const void *a, const void *b)
0092 {
0093 const struct tep_filter_type *ea = a;
0094 const struct tep_filter_type *eb = b;
0095
0096 if (ea->event_id < eb->event_id)
0097 return -1;
0098
0099 if (ea->event_id > eb->event_id)
0100 return 1;
0101
0102 return 0;
0103 }
0104
0105 static struct tep_filter_type *
0106 find_filter_type(struct tep_event_filter *filter, int id)
0107 {
0108 struct tep_filter_type *filter_type;
0109 struct tep_filter_type key;
0110
0111 key.event_id = id;
0112
0113 filter_type = bsearch(&key, filter->event_filters,
0114 filter->filters,
0115 sizeof(*filter->event_filters),
0116 filter_cmp);
0117
0118 return filter_type;
0119 }
0120
0121 static struct tep_filter_type *
0122 add_filter_type(struct tep_event_filter *filter, int id)
0123 {
0124 struct tep_filter_type *filter_type;
0125 int i;
0126
0127 filter_type = find_filter_type(filter, id);
0128 if (filter_type)
0129 return filter_type;
0130
0131 filter_type = realloc(filter->event_filters,
0132 sizeof(*filter->event_filters) *
0133 (filter->filters + 1));
0134 if (!filter_type)
0135 return NULL;
0136
0137 filter->event_filters = filter_type;
0138
0139 for (i = 0; i < filter->filters; i++) {
0140 if (filter->event_filters[i].event_id > id)
0141 break;
0142 }
0143
0144 if (i < filter->filters)
0145 memmove(&filter->event_filters[i+1],
0146 &filter->event_filters[i],
0147 sizeof(*filter->event_filters) *
0148 (filter->filters - i));
0149
0150 filter_type = &filter->event_filters[i];
0151 filter_type->event_id = id;
0152 filter_type->event = tep_find_event(filter->tep, id);
0153 filter_type->filter = NULL;
0154
0155 filter->filters++;
0156
0157 return filter_type;
0158 }
0159
0160
0161
0162
0163
0164 struct tep_event_filter *tep_filter_alloc(struct tep_handle *tep)
0165 {
0166 struct tep_event_filter *filter;
0167
0168 filter = malloc(sizeof(*filter));
0169 if (filter == NULL)
0170 return NULL;
0171
0172 memset(filter, 0, sizeof(*filter));
0173 filter->tep = tep;
0174 tep_ref(tep);
0175
0176 return filter;
0177 }
0178
0179 static struct tep_filter_arg *allocate_arg(void)
0180 {
0181 return calloc(1, sizeof(struct tep_filter_arg));
0182 }
0183
0184 static void free_arg(struct tep_filter_arg *arg)
0185 {
0186 if (!arg)
0187 return;
0188
0189 switch (arg->type) {
0190 case TEP_FILTER_ARG_NONE:
0191 case TEP_FILTER_ARG_BOOLEAN:
0192 break;
0193
0194 case TEP_FILTER_ARG_NUM:
0195 free_arg(arg->num.left);
0196 free_arg(arg->num.right);
0197 break;
0198
0199 case TEP_FILTER_ARG_EXP:
0200 free_arg(arg->exp.left);
0201 free_arg(arg->exp.right);
0202 break;
0203
0204 case TEP_FILTER_ARG_STR:
0205 free(arg->str.val);
0206 regfree(&arg->str.reg);
0207 free(arg->str.buffer);
0208 break;
0209
0210 case TEP_FILTER_ARG_VALUE:
0211 if (arg->value.type == TEP_FILTER_STRING ||
0212 arg->value.type == TEP_FILTER_CHAR)
0213 free(arg->value.str);
0214 break;
0215
0216 case TEP_FILTER_ARG_OP:
0217 free_arg(arg->op.left);
0218 free_arg(arg->op.right);
0219 default:
0220 break;
0221 }
0222
0223 free(arg);
0224 }
0225
0226 static int add_event(struct event_list **events,
0227 struct tep_event *event)
0228 {
0229 struct event_list *list;
0230
0231 list = malloc(sizeof(*list));
0232 if (list == NULL)
0233 return -1;
0234
0235 list->next = *events;
0236 *events = list;
0237 list->event = event;
0238 return 0;
0239 }
0240
0241 static int event_match(struct tep_event *event,
0242 regex_t *sreg, regex_t *ereg)
0243 {
0244 if (sreg) {
0245 return !regexec(sreg, event->system, 0, NULL, 0) &&
0246 !regexec(ereg, event->name, 0, NULL, 0);
0247 }
0248
0249 return !regexec(ereg, event->system, 0, NULL, 0) ||
0250 !regexec(ereg, event->name, 0, NULL, 0);
0251 }
0252
0253 static enum tep_errno
0254 find_event(struct tep_handle *tep, struct event_list **events,
0255 char *sys_name, char *event_name)
0256 {
0257 struct tep_event *event;
0258 regex_t ereg;
0259 regex_t sreg;
0260 int match = 0;
0261 int fail = 0;
0262 char *reg;
0263 int ret;
0264 int i;
0265
0266 if (!event_name) {
0267
0268 event_name = sys_name;
0269 sys_name = NULL;
0270 }
0271
0272 ret = asprintf(®, "^%s$", event_name);
0273 if (ret < 0)
0274 return TEP_ERRNO__MEM_ALLOC_FAILED;
0275
0276 ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
0277 free(reg);
0278
0279 if (ret)
0280 return TEP_ERRNO__INVALID_EVENT_NAME;
0281
0282 if (sys_name) {
0283 ret = asprintf(®, "^%s$", sys_name);
0284 if (ret < 0) {
0285 regfree(&ereg);
0286 return TEP_ERRNO__MEM_ALLOC_FAILED;
0287 }
0288
0289 ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
0290 free(reg);
0291 if (ret) {
0292 regfree(&ereg);
0293 return TEP_ERRNO__INVALID_EVENT_NAME;
0294 }
0295 }
0296
0297 for (i = 0; i < tep->nr_events; i++) {
0298 event = tep->events[i];
0299 if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
0300 match = 1;
0301 if (add_event(events, event) < 0) {
0302 fail = 1;
0303 break;
0304 }
0305 }
0306 }
0307
0308 regfree(&ereg);
0309 if (sys_name)
0310 regfree(&sreg);
0311
0312 if (!match)
0313 return TEP_ERRNO__EVENT_NOT_FOUND;
0314 if (fail)
0315 return TEP_ERRNO__MEM_ALLOC_FAILED;
0316
0317 return 0;
0318 }
0319
0320 static void free_events(struct event_list *events)
0321 {
0322 struct event_list *event;
0323
0324 while (events) {
0325 event = events;
0326 events = events->next;
0327 free(event);
0328 }
0329 }
0330
0331 static enum tep_errno
0332 create_arg_item(struct tep_event *event, const char *token,
0333 enum tep_event_type type, struct tep_filter_arg **parg, char *error_str)
0334 {
0335 struct tep_format_field *field;
0336 struct tep_filter_arg *arg;
0337
0338 arg = allocate_arg();
0339 if (arg == NULL) {
0340 show_error(error_str, "failed to allocate filter arg");
0341 return TEP_ERRNO__MEM_ALLOC_FAILED;
0342 }
0343
0344 switch (type) {
0345
0346 case TEP_EVENT_SQUOTE:
0347 case TEP_EVENT_DQUOTE:
0348 arg->type = TEP_FILTER_ARG_VALUE;
0349 arg->value.type =
0350 type == TEP_EVENT_DQUOTE ? TEP_FILTER_STRING : TEP_FILTER_CHAR;
0351 arg->value.str = strdup(token);
0352 if (!arg->value.str) {
0353 free_arg(arg);
0354 show_error(error_str, "failed to allocate string filter arg");
0355 return TEP_ERRNO__MEM_ALLOC_FAILED;
0356 }
0357 break;
0358 case TEP_EVENT_ITEM:
0359
0360 if (isdigit(token[0])) {
0361 arg->type = TEP_FILTER_ARG_VALUE;
0362 arg->value.type = TEP_FILTER_NUMBER;
0363 arg->value.val = strtoull(token, NULL, 0);
0364 break;
0365 }
0366
0367 field = tep_find_any_field(event, token);
0368 if (!field) {
0369
0370 if (strcmp(token, COMM) == 0) {
0371 field = &comm;
0372 } else if (strcmp(token, CPU) == 0) {
0373 field = &cpu;
0374 } else {
0375
0376 arg->type = TEP_FILTER_ARG_BOOLEAN;
0377 arg->boolean.value = TEP_FILTER_FALSE;
0378 break;
0379 }
0380 }
0381 arg->type = TEP_FILTER_ARG_FIELD;
0382 arg->field.field = field;
0383 break;
0384 default:
0385 free_arg(arg);
0386 show_error(error_str, "expected a value but found %s", token);
0387 return TEP_ERRNO__UNEXPECTED_TYPE;
0388 }
0389 *parg = arg;
0390 return 0;
0391 }
0392
0393 static struct tep_filter_arg *
0394 create_arg_op(enum tep_filter_op_type btype)
0395 {
0396 struct tep_filter_arg *arg;
0397
0398 arg = allocate_arg();
0399 if (!arg)
0400 return NULL;
0401
0402 arg->type = TEP_FILTER_ARG_OP;
0403 arg->op.type = btype;
0404
0405 return arg;
0406 }
0407
0408 static struct tep_filter_arg *
0409 create_arg_exp(enum tep_filter_exp_type etype)
0410 {
0411 struct tep_filter_arg *arg;
0412
0413 arg = allocate_arg();
0414 if (!arg)
0415 return NULL;
0416
0417 arg->type = TEP_FILTER_ARG_EXP;
0418 arg->exp.type = etype;
0419
0420 return arg;
0421 }
0422
0423 static struct tep_filter_arg *
0424 create_arg_cmp(enum tep_filter_cmp_type ctype)
0425 {
0426 struct tep_filter_arg *arg;
0427
0428 arg = allocate_arg();
0429 if (!arg)
0430 return NULL;
0431
0432
0433 arg->type = TEP_FILTER_ARG_NUM;
0434 arg->num.type = ctype;
0435
0436 return arg;
0437 }
0438
0439 static enum tep_errno
0440 add_right(struct tep_filter_arg *op, struct tep_filter_arg *arg, char *error_str)
0441 {
0442 struct tep_filter_arg *left;
0443 char *str;
0444 int op_type;
0445 int ret;
0446
0447 switch (op->type) {
0448 case TEP_FILTER_ARG_EXP:
0449 if (op->exp.right)
0450 goto out_fail;
0451 op->exp.right = arg;
0452 break;
0453
0454 case TEP_FILTER_ARG_OP:
0455 if (op->op.right)
0456 goto out_fail;
0457 op->op.right = arg;
0458 break;
0459
0460 case TEP_FILTER_ARG_NUM:
0461 if (op->op.right)
0462 goto out_fail;
0463
0464
0465
0466 switch (arg->type) {
0467 case TEP_FILTER_ARG_VALUE:
0468 case TEP_FILTER_ARG_FIELD:
0469 break;
0470 default:
0471 show_error(error_str, "Illegal rvalue");
0472 return TEP_ERRNO__ILLEGAL_RVALUE;
0473 }
0474
0475
0476
0477
0478
0479 switch (arg->value.type) {
0480 case TEP_FILTER_CHAR:
0481
0482
0483
0484
0485
0486 if (strlen(arg->value.str) == 1 &&
0487 op->num.type != TEP_FILTER_CMP_REGEX &&
0488 op->num.type != TEP_FILTER_CMP_NOT_REGEX) {
0489 arg->value.type = TEP_FILTER_NUMBER;
0490 goto do_int;
0491 }
0492
0493 case TEP_FILTER_STRING:
0494
0495
0496 op_type = op->num.type;
0497 left = op->num.left;
0498 str = arg->value.str;
0499
0500
0501 memset(op, 0, sizeof(*op));
0502
0503
0504
0505
0506
0507 if (left->type == TEP_FILTER_ARG_BOOLEAN) {
0508 free_arg(left);
0509 free_arg(arg);
0510 op->type = TEP_FILTER_ARG_BOOLEAN;
0511 op->boolean.value = TEP_FILTER_FALSE;
0512 break;
0513 }
0514
0515
0516 if (left->type != TEP_FILTER_ARG_FIELD) {
0517 show_error(error_str,
0518 "Illegal lvalue for string comparison");
0519 return TEP_ERRNO__ILLEGAL_LVALUE;
0520 }
0521
0522
0523 switch (op_type) {
0524 case TEP_FILTER_CMP_EQ:
0525 op_type = TEP_FILTER_CMP_MATCH;
0526 break;
0527 case TEP_FILTER_CMP_NE:
0528 op_type = TEP_FILTER_CMP_NOT_MATCH;
0529 break;
0530
0531 case TEP_FILTER_CMP_REGEX:
0532 case TEP_FILTER_CMP_NOT_REGEX:
0533 ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB);
0534 if (ret) {
0535 show_error(error_str,
0536 "RegEx '%s' did not compute",
0537 str);
0538 return TEP_ERRNO__INVALID_REGEX;
0539 }
0540 break;
0541 default:
0542 show_error(error_str,
0543 "Illegal comparison for string");
0544 return TEP_ERRNO__ILLEGAL_STRING_CMP;
0545 }
0546
0547 op->type = TEP_FILTER_ARG_STR;
0548 op->str.type = op_type;
0549 op->str.field = left->field.field;
0550 op->str.val = strdup(str);
0551 if (!op->str.val) {
0552 show_error(error_str, "Failed to allocate string filter");
0553 return TEP_ERRNO__MEM_ALLOC_FAILED;
0554 }
0555
0556
0557
0558 op->str.buffer = malloc(op->str.field->size + 1);
0559 if (!op->str.buffer) {
0560 show_error(error_str, "Failed to allocate string filter");
0561 return TEP_ERRNO__MEM_ALLOC_FAILED;
0562 }
0563
0564 op->str.buffer[op->str.field->size] = 0;
0565
0566
0567 free_arg(arg);
0568 free_arg(left);
0569
0570 break;
0571
0572 case TEP_FILTER_NUMBER:
0573
0574 do_int:
0575 switch (op->num.type) {
0576 case TEP_FILTER_CMP_REGEX:
0577 case TEP_FILTER_CMP_NOT_REGEX:
0578 show_error(error_str,
0579 "Op not allowed with integers");
0580 return TEP_ERRNO__ILLEGAL_INTEGER_CMP;
0581
0582 default:
0583 break;
0584 }
0585
0586
0587 op->num.right = arg;
0588 break;
0589 default:
0590 goto out_fail;
0591 }
0592 break;
0593 default:
0594 goto out_fail;
0595 }
0596
0597 return 0;
0598
0599 out_fail:
0600 show_error(error_str, "Syntax error");
0601 return TEP_ERRNO__SYNTAX_ERROR;
0602 }
0603
0604 static struct tep_filter_arg *
0605 rotate_op_right(struct tep_filter_arg *a, struct tep_filter_arg *b)
0606 {
0607 struct tep_filter_arg *arg;
0608
0609 arg = a->op.right;
0610 a->op.right = b;
0611 return arg;
0612 }
0613
0614 static enum tep_errno add_left(struct tep_filter_arg *op, struct tep_filter_arg *arg)
0615 {
0616 switch (op->type) {
0617 case TEP_FILTER_ARG_EXP:
0618 if (arg->type == TEP_FILTER_ARG_OP)
0619 arg = rotate_op_right(arg, op);
0620 op->exp.left = arg;
0621 break;
0622
0623 case TEP_FILTER_ARG_OP:
0624 op->op.left = arg;
0625 break;
0626 case TEP_FILTER_ARG_NUM:
0627 if (arg->type == TEP_FILTER_ARG_OP)
0628 arg = rotate_op_right(arg, op);
0629
0630
0631 if (arg->type != TEP_FILTER_ARG_FIELD &&
0632 arg->type != TEP_FILTER_ARG_BOOLEAN)
0633 return TEP_ERRNO__INVALID_ARG_TYPE;
0634 op->num.left = arg;
0635 break;
0636 default:
0637 return TEP_ERRNO__INVALID_ARG_TYPE;
0638 }
0639 return 0;
0640 }
0641
0642 enum op_type {
0643 OP_NONE,
0644 OP_BOOL,
0645 OP_NOT,
0646 OP_EXP,
0647 OP_CMP,
0648 };
0649
0650 static enum op_type process_op(const char *token,
0651 enum tep_filter_op_type *btype,
0652 enum tep_filter_cmp_type *ctype,
0653 enum tep_filter_exp_type *etype)
0654 {
0655 *btype = TEP_FILTER_OP_NOT;
0656 *etype = TEP_FILTER_EXP_NONE;
0657 *ctype = TEP_FILTER_CMP_NONE;
0658
0659 if (strcmp(token, "&&") == 0)
0660 *btype = TEP_FILTER_OP_AND;
0661 else if (strcmp(token, "||") == 0)
0662 *btype = TEP_FILTER_OP_OR;
0663 else if (strcmp(token, "!") == 0)
0664 return OP_NOT;
0665
0666 if (*btype != TEP_FILTER_OP_NOT)
0667 return OP_BOOL;
0668
0669
0670 if (strcmp(token, "+") == 0) {
0671 *etype = TEP_FILTER_EXP_ADD;
0672 } else if (strcmp(token, "-") == 0) {
0673 *etype = TEP_FILTER_EXP_SUB;
0674 } else if (strcmp(token, "*") == 0) {
0675 *etype = TEP_FILTER_EXP_MUL;
0676 } else if (strcmp(token, "/") == 0) {
0677 *etype = TEP_FILTER_EXP_DIV;
0678 } else if (strcmp(token, "%") == 0) {
0679 *etype = TEP_FILTER_EXP_MOD;
0680 } else if (strcmp(token, ">>") == 0) {
0681 *etype = TEP_FILTER_EXP_RSHIFT;
0682 } else if (strcmp(token, "<<") == 0) {
0683 *etype = TEP_FILTER_EXP_LSHIFT;
0684 } else if (strcmp(token, "&") == 0) {
0685 *etype = TEP_FILTER_EXP_AND;
0686 } else if (strcmp(token, "|") == 0) {
0687 *etype = TEP_FILTER_EXP_OR;
0688 } else if (strcmp(token, "^") == 0) {
0689 *etype = TEP_FILTER_EXP_XOR;
0690 } else if (strcmp(token, "~") == 0)
0691 *etype = TEP_FILTER_EXP_NOT;
0692
0693 if (*etype != TEP_FILTER_EXP_NONE)
0694 return OP_EXP;
0695
0696
0697 if (strcmp(token, "==") == 0)
0698 *ctype = TEP_FILTER_CMP_EQ;
0699 else if (strcmp(token, "!=") == 0)
0700 *ctype = TEP_FILTER_CMP_NE;
0701 else if (strcmp(token, "<") == 0)
0702 *ctype = TEP_FILTER_CMP_LT;
0703 else if (strcmp(token, ">") == 0)
0704 *ctype = TEP_FILTER_CMP_GT;
0705 else if (strcmp(token, "<=") == 0)
0706 *ctype = TEP_FILTER_CMP_LE;
0707 else if (strcmp(token, ">=") == 0)
0708 *ctype = TEP_FILTER_CMP_GE;
0709 else if (strcmp(token, "=~") == 0)
0710 *ctype = TEP_FILTER_CMP_REGEX;
0711 else if (strcmp(token, "!~") == 0)
0712 *ctype = TEP_FILTER_CMP_NOT_REGEX;
0713 else
0714 return OP_NONE;
0715
0716 return OP_CMP;
0717 }
0718
0719 static int check_op_done(struct tep_filter_arg *arg)
0720 {
0721 switch (arg->type) {
0722 case TEP_FILTER_ARG_EXP:
0723 return arg->exp.right != NULL;
0724
0725 case TEP_FILTER_ARG_OP:
0726 return arg->op.right != NULL;
0727
0728 case TEP_FILTER_ARG_NUM:
0729 return arg->num.right != NULL;
0730
0731 case TEP_FILTER_ARG_STR:
0732
0733 return 1;
0734
0735 case TEP_FILTER_ARG_BOOLEAN:
0736
0737 return 1;
0738
0739 default:
0740 return 0;
0741 }
0742 }
0743
0744 enum filter_vals {
0745 FILTER_VAL_NORM,
0746 FILTER_VAL_FALSE,
0747 FILTER_VAL_TRUE,
0748 };
0749
0750 static enum tep_errno
0751 reparent_op_arg(struct tep_filter_arg *parent, struct tep_filter_arg *old_child,
0752 struct tep_filter_arg *arg, char *error_str)
0753 {
0754 struct tep_filter_arg *other_child;
0755 struct tep_filter_arg **ptr;
0756
0757 if (parent->type != TEP_FILTER_ARG_OP &&
0758 arg->type != TEP_FILTER_ARG_OP) {
0759 show_error(error_str, "can not reparent other than OP");
0760 return TEP_ERRNO__REPARENT_NOT_OP;
0761 }
0762
0763
0764 if (old_child->op.right == arg) {
0765 ptr = &old_child->op.right;
0766 other_child = old_child->op.left;
0767 } else if (old_child->op.left == arg) {
0768 ptr = &old_child->op.left;
0769 other_child = old_child->op.right;
0770 } else {
0771 show_error(error_str, "Error in reparent op, find other child");
0772 return TEP_ERRNO__REPARENT_FAILED;
0773 }
0774
0775
0776 *ptr = NULL;
0777
0778
0779 if (parent == old_child) {
0780 free_arg(other_child);
0781 *parent = *arg;
0782
0783 free(arg);
0784 return 0;
0785 }
0786
0787 if (parent->op.right == old_child)
0788 ptr = &parent->op.right;
0789 else if (parent->op.left == old_child)
0790 ptr = &parent->op.left;
0791 else {
0792 show_error(error_str, "Error in reparent op");
0793 return TEP_ERRNO__REPARENT_FAILED;
0794 }
0795
0796 *ptr = arg;
0797
0798 free_arg(old_child);
0799 return 0;
0800 }
0801
0802
0803 static int test_arg(struct tep_filter_arg *parent, struct tep_filter_arg *arg,
0804 char *error_str)
0805 {
0806 int lval, rval;
0807
0808 switch (arg->type) {
0809
0810
0811 case TEP_FILTER_ARG_BOOLEAN:
0812 return FILTER_VAL_FALSE + arg->boolean.value;
0813
0814
0815 case TEP_FILTER_ARG_STR:
0816 case TEP_FILTER_ARG_VALUE:
0817 case TEP_FILTER_ARG_FIELD:
0818 return FILTER_VAL_NORM;
0819
0820 case TEP_FILTER_ARG_EXP:
0821 lval = test_arg(arg, arg->exp.left, error_str);
0822 if (lval != FILTER_VAL_NORM)
0823 return lval;
0824 rval = test_arg(arg, arg->exp.right, error_str);
0825 if (rval != FILTER_VAL_NORM)
0826 return rval;
0827 return FILTER_VAL_NORM;
0828
0829 case TEP_FILTER_ARG_NUM:
0830 lval = test_arg(arg, arg->num.left, error_str);
0831 if (lval != FILTER_VAL_NORM)
0832 return lval;
0833 rval = test_arg(arg, arg->num.right, error_str);
0834 if (rval != FILTER_VAL_NORM)
0835 return rval;
0836 return FILTER_VAL_NORM;
0837
0838 case TEP_FILTER_ARG_OP:
0839 if (arg->op.type != TEP_FILTER_OP_NOT) {
0840 lval = test_arg(arg, arg->op.left, error_str);
0841 switch (lval) {
0842 case FILTER_VAL_NORM:
0843 break;
0844 case FILTER_VAL_TRUE:
0845 if (arg->op.type == TEP_FILTER_OP_OR)
0846 return FILTER_VAL_TRUE;
0847 rval = test_arg(arg, arg->op.right, error_str);
0848 if (rval != FILTER_VAL_NORM)
0849 return rval;
0850
0851 return reparent_op_arg(parent, arg, arg->op.right,
0852 error_str);
0853
0854 case FILTER_VAL_FALSE:
0855 if (arg->op.type == TEP_FILTER_OP_AND)
0856 return FILTER_VAL_FALSE;
0857 rval = test_arg(arg, arg->op.right, error_str);
0858 if (rval != FILTER_VAL_NORM)
0859 return rval;
0860
0861 return reparent_op_arg(parent, arg, arg->op.right,
0862 error_str);
0863
0864 default:
0865 return lval;
0866 }
0867 }
0868
0869 rval = test_arg(arg, arg->op.right, error_str);
0870 switch (rval) {
0871 case FILTER_VAL_NORM:
0872 default:
0873 break;
0874
0875 case FILTER_VAL_TRUE:
0876 if (arg->op.type == TEP_FILTER_OP_OR)
0877 return FILTER_VAL_TRUE;
0878 if (arg->op.type == TEP_FILTER_OP_NOT)
0879 return FILTER_VAL_FALSE;
0880
0881 return reparent_op_arg(parent, arg, arg->op.left,
0882 error_str);
0883
0884 case FILTER_VAL_FALSE:
0885 if (arg->op.type == TEP_FILTER_OP_AND)
0886 return FILTER_VAL_FALSE;
0887 if (arg->op.type == TEP_FILTER_OP_NOT)
0888 return FILTER_VAL_TRUE;
0889
0890 return reparent_op_arg(parent, arg, arg->op.left,
0891 error_str);
0892 }
0893
0894 return rval;
0895 default:
0896 show_error(error_str, "bad arg in filter tree");
0897 return TEP_ERRNO__BAD_FILTER_ARG;
0898 }
0899 return FILTER_VAL_NORM;
0900 }
0901
0902
0903 static int collapse_tree(struct tep_filter_arg *arg,
0904 struct tep_filter_arg **arg_collapsed, char *error_str)
0905 {
0906 int ret;
0907
0908 ret = test_arg(arg, arg, error_str);
0909 switch (ret) {
0910 case FILTER_VAL_NORM:
0911 break;
0912
0913 case FILTER_VAL_TRUE:
0914 case FILTER_VAL_FALSE:
0915 free_arg(arg);
0916 arg = allocate_arg();
0917 if (arg) {
0918 arg->type = TEP_FILTER_ARG_BOOLEAN;
0919 arg->boolean.value = ret == FILTER_VAL_TRUE;
0920 } else {
0921 show_error(error_str, "Failed to allocate filter arg");
0922 ret = TEP_ERRNO__MEM_ALLOC_FAILED;
0923 }
0924 break;
0925
0926 default:
0927
0928 free_arg(arg);
0929 arg = NULL;
0930 break;
0931 }
0932
0933 *arg_collapsed = arg;
0934 return ret;
0935 }
0936
0937 static enum tep_errno
0938 process_filter(struct tep_event *event, struct tep_filter_arg **parg,
0939 char *error_str, int not)
0940 {
0941 enum tep_event_type type;
0942 char *token = NULL;
0943 struct tep_filter_arg *current_op = NULL;
0944 struct tep_filter_arg *current_exp = NULL;
0945 struct tep_filter_arg *left_item = NULL;
0946 struct tep_filter_arg *arg = NULL;
0947 enum op_type op_type;
0948 enum tep_filter_op_type btype;
0949 enum tep_filter_exp_type etype;
0950 enum tep_filter_cmp_type ctype;
0951 enum tep_errno ret;
0952
0953 *parg = NULL;
0954
0955 do {
0956 free(token);
0957 type = filter_read_token(&token);
0958 switch (type) {
0959 case TEP_EVENT_SQUOTE:
0960 case TEP_EVENT_DQUOTE:
0961 case TEP_EVENT_ITEM:
0962 ret = create_arg_item(event, token, type, &arg, error_str);
0963 if (ret < 0)
0964 goto fail;
0965 if (!left_item)
0966 left_item = arg;
0967 else if (current_exp) {
0968 ret = add_right(current_exp, arg, error_str);
0969 if (ret < 0)
0970 goto fail;
0971 left_item = NULL;
0972
0973 if (not) {
0974 arg = NULL;
0975 if (current_op)
0976 goto fail_syntax;
0977 free(token);
0978 *parg = current_exp;
0979 return 0;
0980 }
0981 } else
0982 goto fail_syntax;
0983 arg = NULL;
0984 break;
0985
0986 case TEP_EVENT_DELIM:
0987 if (*token == ',') {
0988 show_error(error_str, "Illegal token ','");
0989 ret = TEP_ERRNO__ILLEGAL_TOKEN;
0990 goto fail;
0991 }
0992
0993 if (*token == '(') {
0994 if (left_item) {
0995 show_error(error_str,
0996 "Open paren can not come after item");
0997 ret = TEP_ERRNO__INVALID_PAREN;
0998 goto fail;
0999 }
1000 if (current_exp) {
1001 show_error(error_str,
1002 "Open paren can not come after expression");
1003 ret = TEP_ERRNO__INVALID_PAREN;
1004 goto fail;
1005 }
1006
1007 ret = process_filter(event, &arg, error_str, 0);
1008 if (ret != TEP_ERRNO__UNBALANCED_PAREN) {
1009 if (ret == 0) {
1010 show_error(error_str,
1011 "Unbalanced number of '('");
1012 ret = TEP_ERRNO__UNBALANCED_PAREN;
1013 }
1014 goto fail;
1015 }
1016 ret = 0;
1017
1018
1019 if (not) {
1020 if (current_op)
1021 goto fail_syntax;
1022 *parg = arg;
1023 return 0;
1024 }
1025
1026 if (current_op)
1027 ret = add_right(current_op, arg, error_str);
1028 else
1029 current_exp = arg;
1030
1031 if (ret < 0)
1032 goto fail;
1033
1034 } else {
1035 if (!current_op && !current_exp)
1036 goto fail_syntax;
1037
1038
1039 if (current_exp && !check_op_done(current_exp))
1040 goto fail_syntax;
1041 if (current_op && !check_op_done(current_op))
1042 goto fail_syntax;
1043
1044 if (current_op)
1045 *parg = current_op;
1046 else
1047 *parg = current_exp;
1048 free(token);
1049 return TEP_ERRNO__UNBALANCED_PAREN;
1050 }
1051 break;
1052
1053 case TEP_EVENT_OP:
1054 op_type = process_op(token, &btype, &ctype, &etype);
1055
1056
1057 switch (op_type) {
1058 case OP_BOOL:
1059
1060 if (!current_exp && !current_op)
1061 goto fail_syntax;
1062
1063 case OP_NOT:
1064
1065 if (left_item)
1066 goto fail_syntax;
1067 break;
1068 case OP_EXP:
1069 case OP_CMP:
1070 if (!left_item)
1071 goto fail_syntax;
1072 break;
1073 case OP_NONE:
1074 show_error(error_str,
1075 "Unknown op token %s", token);
1076 ret = TEP_ERRNO__UNKNOWN_TOKEN;
1077 goto fail;
1078 }
1079
1080 ret = 0;
1081 switch (op_type) {
1082 case OP_BOOL:
1083 arg = create_arg_op(btype);
1084 if (arg == NULL)
1085 goto fail_alloc;
1086 if (current_op)
1087 ret = add_left(arg, current_op);
1088 else
1089 ret = add_left(arg, current_exp);
1090 current_op = arg;
1091 current_exp = NULL;
1092 break;
1093
1094 case OP_NOT:
1095 arg = create_arg_op(btype);
1096 if (arg == NULL)
1097 goto fail_alloc;
1098 if (current_op)
1099 ret = add_right(current_op, arg, error_str);
1100 if (ret < 0)
1101 goto fail;
1102 current_exp = arg;
1103 ret = process_filter(event, &arg, error_str, 1);
1104 if (ret < 0)
1105 goto fail;
1106 ret = add_right(current_exp, arg, error_str);
1107 if (ret < 0)
1108 goto fail;
1109 break;
1110
1111 case OP_EXP:
1112 case OP_CMP:
1113 if (op_type == OP_EXP)
1114 arg = create_arg_exp(etype);
1115 else
1116 arg = create_arg_cmp(ctype);
1117 if (arg == NULL)
1118 goto fail_alloc;
1119
1120 if (current_op)
1121 ret = add_right(current_op, arg, error_str);
1122 if (ret < 0)
1123 goto fail;
1124 ret = add_left(arg, left_item);
1125 if (ret < 0) {
1126 arg = NULL;
1127 goto fail_syntax;
1128 }
1129 current_exp = arg;
1130 break;
1131 default:
1132 break;
1133 }
1134 arg = NULL;
1135 if (ret < 0)
1136 goto fail_syntax;
1137 break;
1138 case TEP_EVENT_NONE:
1139 break;
1140 case TEP_EVENT_ERROR:
1141 goto fail_alloc;
1142 default:
1143 goto fail_syntax;
1144 }
1145 } while (type != TEP_EVENT_NONE);
1146
1147 if (!current_op && !current_exp)
1148 goto fail_syntax;
1149
1150 if (!current_op)
1151 current_op = current_exp;
1152
1153 ret = collapse_tree(current_op, parg, error_str);
1154
1155 current_op = NULL;
1156 if (ret < 0)
1157 goto fail;
1158
1159 free(token);
1160 return 0;
1161
1162 fail_alloc:
1163 show_error(error_str, "failed to allocate filter arg");
1164 ret = TEP_ERRNO__MEM_ALLOC_FAILED;
1165 goto fail;
1166 fail_syntax:
1167 show_error(error_str, "Syntax error");
1168 ret = TEP_ERRNO__SYNTAX_ERROR;
1169 fail:
1170 free_arg(current_op);
1171 free_arg(current_exp);
1172 free_arg(arg);
1173 free(token);
1174 return ret;
1175 }
1176
1177 static enum tep_errno
1178 process_event(struct tep_event *event, const char *filter_str,
1179 struct tep_filter_arg **parg, char *error_str)
1180 {
1181 int ret;
1182
1183 init_input_buf(filter_str, strlen(filter_str));
1184
1185 ret = process_filter(event, parg, error_str, 0);
1186 if (ret < 0)
1187 return ret;
1188
1189
1190 if (!*parg) {
1191 *parg = allocate_arg();
1192 if (*parg == NULL)
1193 return TEP_ERRNO__MEM_ALLOC_FAILED;
1194
1195 (*parg)->type = TEP_FILTER_ARG_BOOLEAN;
1196 (*parg)->boolean.value = TEP_FILTER_FALSE;
1197 }
1198
1199 return 0;
1200 }
1201
1202 static enum tep_errno
1203 filter_event(struct tep_event_filter *filter, struct tep_event *event,
1204 const char *filter_str, char *error_str)
1205 {
1206 struct tep_filter_type *filter_type;
1207 struct tep_filter_arg *arg;
1208 enum tep_errno ret;
1209
1210 if (filter_str) {
1211 ret = process_event(event, filter_str, &arg, error_str);
1212 if (ret < 0)
1213 return ret;
1214
1215 } else {
1216
1217 arg = allocate_arg();
1218 if (arg == NULL)
1219 return TEP_ERRNO__MEM_ALLOC_FAILED;
1220
1221 arg->type = TEP_FILTER_ARG_BOOLEAN;
1222 arg->boolean.value = TEP_FILTER_TRUE;
1223 }
1224
1225 filter_type = add_filter_type(filter, event->id);
1226 if (filter_type == NULL) {
1227 free_arg(arg);
1228 return TEP_ERRNO__MEM_ALLOC_FAILED;
1229 }
1230
1231 if (filter_type->filter)
1232 free_arg(filter_type->filter);
1233 filter_type->filter = arg;
1234
1235 return 0;
1236 }
1237
1238 static void filter_init_error_buf(struct tep_event_filter *filter)
1239 {
1240
1241 init_input_buf("", 0);
1242 filter->error_buffer[0] = '\0';
1243 }
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254 enum tep_errno tep_filter_add_filter_str(struct tep_event_filter *filter,
1255 const char *filter_str)
1256 {
1257 struct tep_handle *tep = filter->tep;
1258 struct event_list *event;
1259 struct event_list *events = NULL;
1260 const char *filter_start;
1261 const char *next_event;
1262 char *this_event;
1263 char *event_name = NULL;
1264 char *sys_name = NULL;
1265 char *sp;
1266 enum tep_errno rtn = 0;
1267 int len;
1268 int ret;
1269
1270 filter_init_error_buf(filter);
1271
1272 filter_start = strchr(filter_str, ':');
1273 if (filter_start)
1274 len = filter_start - filter_str;
1275 else
1276 len = strlen(filter_str);
1277
1278 do {
1279 next_event = strchr(filter_str, ',');
1280 if (next_event &&
1281 (!filter_start || next_event < filter_start))
1282 len = next_event - filter_str;
1283 else if (filter_start)
1284 len = filter_start - filter_str;
1285 else
1286 len = strlen(filter_str);
1287
1288 this_event = malloc(len + 1);
1289 if (this_event == NULL) {
1290
1291 free_events(events);
1292 return TEP_ERRNO__MEM_ALLOC_FAILED;
1293 }
1294 memcpy(this_event, filter_str, len);
1295 this_event[len] = 0;
1296
1297 if (next_event)
1298 next_event++;
1299
1300 filter_str = next_event;
1301
1302 sys_name = strtok_r(this_event, "/", &sp);
1303 event_name = strtok_r(NULL, "/", &sp);
1304
1305 if (!sys_name) {
1306
1307 free_events(events);
1308 free(this_event);
1309 return TEP_ERRNO__FILTER_NOT_FOUND;
1310 }
1311
1312
1313 ret = find_event(tep, &events, strim(sys_name), strim(event_name));
1314 if (ret < 0) {
1315 free_events(events);
1316 free(this_event);
1317 return ret;
1318 }
1319 free(this_event);
1320 } while (filter_str);
1321
1322
1323 if (filter_start)
1324 filter_start++;
1325
1326
1327 for (event = events; event; event = event->next) {
1328 ret = filter_event(filter, event->event, filter_start,
1329 filter->error_buffer);
1330
1331 if (ret < 0)
1332 rtn = ret;
1333
1334 if (ret >= 0 && tep->test_filters) {
1335 char *test;
1336 test = tep_filter_make_string(filter, event->event->id);
1337 if (test) {
1338 printf(" '%s: %s'\n", event->event->name, test);
1339 free(test);
1340 }
1341 }
1342 }
1343
1344 free_events(events);
1345
1346 return rtn;
1347 }
1348
1349 static void free_filter_type(struct tep_filter_type *filter_type)
1350 {
1351 free_arg(filter_type->filter);
1352 }
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363 int tep_filter_strerror(struct tep_event_filter *filter, enum tep_errno err,
1364 char *buf, size_t buflen)
1365 {
1366 if (err <= __TEP_ERRNO__START || err >= __TEP_ERRNO__END)
1367 return -1;
1368
1369 if (strlen(filter->error_buffer) > 0) {
1370 size_t len = snprintf(buf, buflen, "%s", filter->error_buffer);
1371
1372 if (len > buflen)
1373 return -1;
1374 return 0;
1375 }
1376
1377 return tep_strerror(filter->tep, err, buf, buflen);
1378 }
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391 int tep_filter_remove_event(struct tep_event_filter *filter,
1392 int event_id)
1393 {
1394 struct tep_filter_type *filter_type;
1395 unsigned long len;
1396
1397 if (!filter->filters)
1398 return 0;
1399
1400 filter_type = find_filter_type(filter, event_id);
1401
1402 if (!filter_type)
1403 return 0;
1404
1405 free_filter_type(filter_type);
1406
1407
1408 len = (unsigned long)(filter->event_filters + filter->filters) -
1409 (unsigned long)(filter_type + 1);
1410
1411 memmove(filter_type, filter_type + 1, len);
1412 filter->filters--;
1413
1414 memset(&filter->event_filters[filter->filters], 0,
1415 sizeof(*filter_type));
1416
1417 return 1;
1418 }
1419
1420
1421
1422
1423
1424
1425
1426 void tep_filter_reset(struct tep_event_filter *filter)
1427 {
1428 int i;
1429
1430 for (i = 0; i < filter->filters; i++)
1431 free_filter_type(&filter->event_filters[i]);
1432
1433 free(filter->event_filters);
1434 filter->filters = 0;
1435 filter->event_filters = NULL;
1436 }
1437
1438 void tep_filter_free(struct tep_event_filter *filter)
1439 {
1440 tep_unref(filter->tep);
1441
1442 tep_filter_reset(filter);
1443
1444 free(filter);
1445 }
1446
1447 static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg);
1448
1449 static int copy_filter_type(struct tep_event_filter *filter,
1450 struct tep_event_filter *source,
1451 struct tep_filter_type *filter_type)
1452 {
1453 struct tep_filter_arg *arg;
1454 struct tep_event *event;
1455 const char *sys;
1456 const char *name;
1457 char *str;
1458
1459
1460 sys = filter_type->event->system;
1461 name = filter_type->event->name;
1462 event = tep_find_event_by_name(filter->tep, sys, name);
1463 if (!event)
1464 return -1;
1465
1466 str = arg_to_str(source, filter_type->filter);
1467 if (!str)
1468 return -1;
1469
1470 if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) {
1471
1472 arg = allocate_arg();
1473 if (arg == NULL) {
1474 free(str);
1475 return -1;
1476 }
1477
1478 arg->type = TEP_FILTER_ARG_BOOLEAN;
1479 if (strcmp(str, "TRUE") == 0)
1480 arg->boolean.value = 1;
1481 else
1482 arg->boolean.value = 0;
1483
1484 filter_type = add_filter_type(filter, event->id);
1485 if (filter_type == NULL) {
1486 free(str);
1487 free_arg(arg);
1488 return -1;
1489 }
1490
1491 filter_type->filter = arg;
1492
1493 free(str);
1494 return 0;
1495 }
1496
1497 filter_event(filter, event, str, NULL);
1498 free(str);
1499
1500 return 0;
1501 }
1502
1503
1504
1505
1506
1507
1508
1509
1510 int tep_filter_copy(struct tep_event_filter *dest, struct tep_event_filter *source)
1511 {
1512 int ret = 0;
1513 int i;
1514
1515 tep_filter_reset(dest);
1516
1517 for (i = 0; i < source->filters; i++) {
1518 if (copy_filter_type(dest, source, &source->event_filters[i]))
1519 ret = -1;
1520 }
1521 return ret;
1522 }
1523
1524 static int test_filter(struct tep_event *event, struct tep_filter_arg *arg,
1525 struct tep_record *record, enum tep_errno *err);
1526
1527 static const char *
1528 get_comm(struct tep_event *event, struct tep_record *record)
1529 {
1530 const char *comm;
1531 int pid;
1532
1533 pid = tep_data_pid(event->tep, record);
1534 comm = tep_data_comm_from_pid(event->tep, pid);
1535 return comm;
1536 }
1537
1538 static unsigned long long
1539 get_value(struct tep_event *event,
1540 struct tep_format_field *field, struct tep_record *record)
1541 {
1542 unsigned long long val;
1543
1544
1545 if (field == &comm) {
1546 const char *name;
1547
1548 name = get_comm(event, record);
1549 return (unsigned long)name;
1550 }
1551
1552
1553 if (field == &cpu)
1554 return record->cpu;
1555
1556 tep_read_number_field(field, record->data, &val);
1557
1558 if (!(field->flags & TEP_FIELD_IS_SIGNED))
1559 return val;
1560
1561 switch (field->size) {
1562 case 1:
1563 return (char)val;
1564 case 2:
1565 return (short)val;
1566 case 4:
1567 return (int)val;
1568 case 8:
1569 return (long long)val;
1570 }
1571 return val;
1572 }
1573
1574 static unsigned long long
1575 get_arg_value(struct tep_event *event, struct tep_filter_arg *arg,
1576 struct tep_record *record, enum tep_errno *err);
1577
1578 static unsigned long long
1579 get_exp_value(struct tep_event *event, struct tep_filter_arg *arg,
1580 struct tep_record *record, enum tep_errno *err)
1581 {
1582 unsigned long long lval, rval;
1583
1584 lval = get_arg_value(event, arg->exp.left, record, err);
1585 rval = get_arg_value(event, arg->exp.right, record, err);
1586
1587 if (*err) {
1588
1589
1590
1591 return 0;
1592 }
1593
1594 switch (arg->exp.type) {
1595 case TEP_FILTER_EXP_ADD:
1596 return lval + rval;
1597
1598 case TEP_FILTER_EXP_SUB:
1599 return lval - rval;
1600
1601 case TEP_FILTER_EXP_MUL:
1602 return lval * rval;
1603
1604 case TEP_FILTER_EXP_DIV:
1605 return lval / rval;
1606
1607 case TEP_FILTER_EXP_MOD:
1608 return lval % rval;
1609
1610 case TEP_FILTER_EXP_RSHIFT:
1611 return lval >> rval;
1612
1613 case TEP_FILTER_EXP_LSHIFT:
1614 return lval << rval;
1615
1616 case TEP_FILTER_EXP_AND:
1617 return lval & rval;
1618
1619 case TEP_FILTER_EXP_OR:
1620 return lval | rval;
1621
1622 case TEP_FILTER_EXP_XOR:
1623 return lval ^ rval;
1624
1625 case TEP_FILTER_EXP_NOT:
1626 default:
1627 if (!*err)
1628 *err = TEP_ERRNO__INVALID_EXP_TYPE;
1629 }
1630 return 0;
1631 }
1632
1633 static unsigned long long
1634 get_arg_value(struct tep_event *event, struct tep_filter_arg *arg,
1635 struct tep_record *record, enum tep_errno *err)
1636 {
1637 switch (arg->type) {
1638 case TEP_FILTER_ARG_FIELD:
1639 return get_value(event, arg->field.field, record);
1640
1641 case TEP_FILTER_ARG_VALUE:
1642 if (arg->value.type != TEP_FILTER_NUMBER) {
1643 if (!*err)
1644 *err = TEP_ERRNO__NOT_A_NUMBER;
1645 }
1646 return arg->value.val;
1647
1648 case TEP_FILTER_ARG_EXP:
1649 return get_exp_value(event, arg, record, err);
1650
1651 default:
1652 if (!*err)
1653 *err = TEP_ERRNO__INVALID_ARG_TYPE;
1654 }
1655 return 0;
1656 }
1657
1658 static int test_num(struct tep_event *event, struct tep_filter_arg *arg,
1659 struct tep_record *record, enum tep_errno *err)
1660 {
1661 unsigned long long lval, rval;
1662
1663 lval = get_arg_value(event, arg->num.left, record, err);
1664 rval = get_arg_value(event, arg->num.right, record, err);
1665
1666 if (*err) {
1667
1668
1669
1670 return 0;
1671 }
1672
1673 switch (arg->num.type) {
1674 case TEP_FILTER_CMP_EQ:
1675 return lval == rval;
1676
1677 case TEP_FILTER_CMP_NE:
1678 return lval != rval;
1679
1680 case TEP_FILTER_CMP_GT:
1681 return lval > rval;
1682
1683 case TEP_FILTER_CMP_LT:
1684 return lval < rval;
1685
1686 case TEP_FILTER_CMP_GE:
1687 return lval >= rval;
1688
1689 case TEP_FILTER_CMP_LE:
1690 return lval <= rval;
1691
1692 default:
1693 if (!*err)
1694 *err = TEP_ERRNO__ILLEGAL_INTEGER_CMP;
1695 return 0;
1696 }
1697 }
1698
1699 static const char *get_field_str(struct tep_filter_arg *arg, struct tep_record *record)
1700 {
1701 struct tep_event *event;
1702 struct tep_handle *tep;
1703 unsigned long long addr;
1704 const char *val = NULL;
1705 unsigned int size;
1706 char hex[64];
1707
1708
1709 if (arg->str.field->flags & TEP_FIELD_IS_STRING) {
1710 val = record->data + arg->str.field->offset;
1711 size = arg->str.field->size;
1712
1713 if (arg->str.field->flags & TEP_FIELD_IS_DYNAMIC) {
1714 addr = *(unsigned int *)val;
1715 size = addr >> 16;
1716 addr &= 0xffff;
1717 if (arg->str.field->flags & TEP_FIELD_IS_RELATIVE)
1718 addr += arg->str.field->offset + arg->str.field->size;
1719 val = record->data + addr;
1720 }
1721
1722
1723
1724
1725
1726 if (*(val + size - 1)) {
1727
1728 memcpy(arg->str.buffer, val, arg->str.field->size);
1729
1730 val = arg->str.buffer;
1731 }
1732
1733 } else {
1734 event = arg->str.field->event;
1735 tep = event->tep;
1736 addr = get_value(event, arg->str.field, record);
1737
1738 if (arg->str.field->flags & (TEP_FIELD_IS_POINTER | TEP_FIELD_IS_LONG))
1739
1740 val = tep_find_function(tep, addr);
1741
1742 if (val == NULL) {
1743
1744 snprintf(hex, 64, "0x%llx", addr);
1745 val = hex;
1746 }
1747 }
1748
1749 return val;
1750 }
1751
1752 static int test_str(struct tep_event *event, struct tep_filter_arg *arg,
1753 struct tep_record *record, enum tep_errno *err)
1754 {
1755 const char *val;
1756
1757 if (arg->str.field == &comm)
1758 val = get_comm(event, record);
1759 else
1760 val = get_field_str(arg, record);
1761
1762 switch (arg->str.type) {
1763 case TEP_FILTER_CMP_MATCH:
1764 return strcmp(val, arg->str.val) == 0;
1765
1766 case TEP_FILTER_CMP_NOT_MATCH:
1767 return strcmp(val, arg->str.val) != 0;
1768
1769 case TEP_FILTER_CMP_REGEX:
1770
1771 return !regexec(&arg->str.reg, val, 0, NULL, 0);
1772
1773 case TEP_FILTER_CMP_NOT_REGEX:
1774 return regexec(&arg->str.reg, val, 0, NULL, 0);
1775
1776 default:
1777 if (!*err)
1778 *err = TEP_ERRNO__ILLEGAL_STRING_CMP;
1779 return 0;
1780 }
1781 }
1782
1783 static int test_op(struct tep_event *event, struct tep_filter_arg *arg,
1784 struct tep_record *record, enum tep_errno *err)
1785 {
1786 switch (arg->op.type) {
1787 case TEP_FILTER_OP_AND:
1788 return test_filter(event, arg->op.left, record, err) &&
1789 test_filter(event, arg->op.right, record, err);
1790
1791 case TEP_FILTER_OP_OR:
1792 return test_filter(event, arg->op.left, record, err) ||
1793 test_filter(event, arg->op.right, record, err);
1794
1795 case TEP_FILTER_OP_NOT:
1796 return !test_filter(event, arg->op.right, record, err);
1797
1798 default:
1799 if (!*err)
1800 *err = TEP_ERRNO__INVALID_OP_TYPE;
1801 return 0;
1802 }
1803 }
1804
1805 static int test_filter(struct tep_event *event, struct tep_filter_arg *arg,
1806 struct tep_record *record, enum tep_errno *err)
1807 {
1808 if (*err) {
1809
1810
1811
1812 return 0;
1813 }
1814
1815 switch (arg->type) {
1816 case TEP_FILTER_ARG_BOOLEAN:
1817
1818 return arg->boolean.value;
1819
1820 case TEP_FILTER_ARG_OP:
1821 return test_op(event, arg, record, err);
1822
1823 case TEP_FILTER_ARG_NUM:
1824 return test_num(event, arg, record, err);
1825
1826 case TEP_FILTER_ARG_STR:
1827 return test_str(event, arg, record, err);
1828
1829 case TEP_FILTER_ARG_EXP:
1830 case TEP_FILTER_ARG_VALUE:
1831 case TEP_FILTER_ARG_FIELD:
1832
1833
1834
1835
1836 return !!get_arg_value(event, arg, record, err);
1837
1838 default:
1839 if (!*err)
1840 *err = TEP_ERRNO__INVALID_ARG_TYPE;
1841 return 0;
1842 }
1843 }
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853 int tep_event_filtered(struct tep_event_filter *filter, int event_id)
1854 {
1855 struct tep_filter_type *filter_type;
1856
1857 if (!filter->filters)
1858 return 0;
1859
1860 filter_type = find_filter_type(filter, event_id);
1861
1862 return filter_type ? 1 : 0;
1863 }
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877 enum tep_errno tep_filter_match(struct tep_event_filter *filter,
1878 struct tep_record *record)
1879 {
1880 struct tep_handle *tep = filter->tep;
1881 struct tep_filter_type *filter_type;
1882 int event_id;
1883 int ret;
1884 enum tep_errno err = 0;
1885
1886 filter_init_error_buf(filter);
1887
1888 if (!filter->filters)
1889 return TEP_ERRNO__NO_FILTER;
1890
1891 event_id = tep_data_type(tep, record);
1892
1893 filter_type = find_filter_type(filter, event_id);
1894 if (!filter_type)
1895 return TEP_ERRNO__FILTER_NOT_FOUND;
1896
1897 ret = test_filter(filter_type->event, filter_type->filter, record, &err);
1898 if (err)
1899 return err;
1900
1901 return ret ? TEP_ERRNO__FILTER_MATCH : TEP_ERRNO__FILTER_MISS;
1902 }
1903
1904 static char *op_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
1905 {
1906 char *str = NULL;
1907 char *left = NULL;
1908 char *right = NULL;
1909 char *op = NULL;
1910 int left_val = -1;
1911 int right_val = -1;
1912 int val;
1913
1914 switch (arg->op.type) {
1915 case TEP_FILTER_OP_AND:
1916 op = "&&";
1917
1918 case TEP_FILTER_OP_OR:
1919 if (!op)
1920 op = "||";
1921
1922 left = arg_to_str(filter, arg->op.left);
1923 right = arg_to_str(filter, arg->op.right);
1924 if (!left || !right)
1925 break;
1926
1927
1928 if (strcmp(left, "TRUE") == 0)
1929 left_val = 1;
1930 else if (strcmp(left, "FALSE") == 0)
1931 left_val = 0;
1932
1933 if (strcmp(right, "TRUE") == 0)
1934 right_val = 1;
1935 else if (strcmp(right, "FALSE") == 0)
1936 right_val = 0;
1937
1938 if (left_val >= 0) {
1939 if ((arg->op.type == TEP_FILTER_OP_AND && !left_val) ||
1940 (arg->op.type == TEP_FILTER_OP_OR && left_val)) {
1941
1942 str = left;
1943 left = NULL;
1944 break;
1945 }
1946 if (right_val >= 0) {
1947
1948 val = 0;
1949 switch (arg->op.type) {
1950 case TEP_FILTER_OP_AND:
1951 val = left_val && right_val;
1952 break;
1953 case TEP_FILTER_OP_OR:
1954 val = left_val || right_val;
1955 break;
1956 default:
1957 break;
1958 }
1959 if (asprintf(&str, val ? "TRUE" : "FALSE") < 0)
1960 str = NULL;
1961 break;
1962 }
1963 }
1964 if (right_val >= 0) {
1965 if ((arg->op.type == TEP_FILTER_OP_AND && !right_val) ||
1966 (arg->op.type == TEP_FILTER_OP_OR && right_val)) {
1967
1968 str = right;
1969 right = NULL;
1970 break;
1971 }
1972
1973 str = left;
1974 left = NULL;
1975 break;
1976 }
1977
1978 if (asprintf(&str, "(%s) %s (%s)", left, op, right) < 0)
1979 str = NULL;
1980 break;
1981
1982 case TEP_FILTER_OP_NOT:
1983 op = "!";
1984 right = arg_to_str(filter, arg->op.right);
1985 if (!right)
1986 break;
1987
1988
1989 if (strcmp(right, "TRUE") == 0)
1990 right_val = 1;
1991 else if (strcmp(right, "FALSE") == 0)
1992 right_val = 0;
1993 if (right_val >= 0) {
1994
1995 if (asprintf(&str, right_val ? "FALSE" : "TRUE") < 0)
1996 str = NULL;
1997 break;
1998 }
1999 if (asprintf(&str, "%s(%s)", op, right) < 0)
2000 str = NULL;
2001 break;
2002
2003 default:
2004
2005 break;
2006 }
2007 free(left);
2008 free(right);
2009 return str;
2010 }
2011
2012 static char *val_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2013 {
2014 char *str = NULL;
2015
2016 if (asprintf(&str, "%lld", arg->value.val) < 0)
2017 str = NULL;
2018
2019 return str;
2020 }
2021
2022 static char *field_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2023 {
2024 return strdup(arg->field.field->name);
2025 }
2026
2027 static char *exp_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2028 {
2029 char *lstr;
2030 char *rstr;
2031 char *op;
2032 char *str = NULL;
2033
2034 lstr = arg_to_str(filter, arg->exp.left);
2035 rstr = arg_to_str(filter, arg->exp.right);
2036 if (!lstr || !rstr)
2037 goto out;
2038
2039 switch (arg->exp.type) {
2040 case TEP_FILTER_EXP_ADD:
2041 op = "+";
2042 break;
2043 case TEP_FILTER_EXP_SUB:
2044 op = "-";
2045 break;
2046 case TEP_FILTER_EXP_MUL:
2047 op = "*";
2048 break;
2049 case TEP_FILTER_EXP_DIV:
2050 op = "/";
2051 break;
2052 case TEP_FILTER_EXP_MOD:
2053 op = "%";
2054 break;
2055 case TEP_FILTER_EXP_RSHIFT:
2056 op = ">>";
2057 break;
2058 case TEP_FILTER_EXP_LSHIFT:
2059 op = "<<";
2060 break;
2061 case TEP_FILTER_EXP_AND:
2062 op = "&";
2063 break;
2064 case TEP_FILTER_EXP_OR:
2065 op = "|";
2066 break;
2067 case TEP_FILTER_EXP_XOR:
2068 op = "^";
2069 break;
2070 default:
2071 op = "[ERROR IN EXPRESSION TYPE]";
2072 break;
2073 }
2074
2075 if (asprintf(&str, "%s %s %s", lstr, op, rstr) < 0)
2076 str = NULL;
2077 out:
2078 free(lstr);
2079 free(rstr);
2080
2081 return str;
2082 }
2083
2084 static char *num_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2085 {
2086 char *lstr;
2087 char *rstr;
2088 char *str = NULL;
2089 char *op = NULL;
2090
2091 lstr = arg_to_str(filter, arg->num.left);
2092 rstr = arg_to_str(filter, arg->num.right);
2093 if (!lstr || !rstr)
2094 goto out;
2095
2096 switch (arg->num.type) {
2097 case TEP_FILTER_CMP_EQ:
2098 op = "==";
2099
2100 case TEP_FILTER_CMP_NE:
2101 if (!op)
2102 op = "!=";
2103
2104 case TEP_FILTER_CMP_GT:
2105 if (!op)
2106 op = ">";
2107
2108 case TEP_FILTER_CMP_LT:
2109 if (!op)
2110 op = "<";
2111
2112 case TEP_FILTER_CMP_GE:
2113 if (!op)
2114 op = ">=";
2115
2116 case TEP_FILTER_CMP_LE:
2117 if (!op)
2118 op = "<=";
2119
2120 if (asprintf(&str, "%s %s %s", lstr, op, rstr) < 0)
2121 str = NULL;
2122 break;
2123
2124 default:
2125
2126 break;
2127 }
2128
2129 out:
2130 free(lstr);
2131 free(rstr);
2132 return str;
2133 }
2134
2135 static char *str_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2136 {
2137 char *str = NULL;
2138 char *op = NULL;
2139
2140 switch (arg->str.type) {
2141 case TEP_FILTER_CMP_MATCH:
2142 op = "==";
2143
2144 case TEP_FILTER_CMP_NOT_MATCH:
2145 if (!op)
2146 op = "!=";
2147
2148 case TEP_FILTER_CMP_REGEX:
2149 if (!op)
2150 op = "=~";
2151
2152 case TEP_FILTER_CMP_NOT_REGEX:
2153 if (!op)
2154 op = "!~";
2155
2156 if (asprintf(&str, "%s %s \"%s\"",
2157 arg->str.field->name, op, arg->str.val) < 0)
2158 str = NULL;
2159 break;
2160
2161 default:
2162
2163 break;
2164 }
2165 return str;
2166 }
2167
2168 static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2169 {
2170 char *str = NULL;
2171
2172 switch (arg->type) {
2173 case TEP_FILTER_ARG_BOOLEAN:
2174 if (asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE") < 0)
2175 str = NULL;
2176 return str;
2177
2178 case TEP_FILTER_ARG_OP:
2179 return op_to_str(filter, arg);
2180
2181 case TEP_FILTER_ARG_NUM:
2182 return num_to_str(filter, arg);
2183
2184 case TEP_FILTER_ARG_STR:
2185 return str_to_str(filter, arg);
2186
2187 case TEP_FILTER_ARG_VALUE:
2188 return val_to_str(filter, arg);
2189
2190 case TEP_FILTER_ARG_FIELD:
2191 return field_to_str(filter, arg);
2192
2193 case TEP_FILTER_ARG_EXP:
2194 return exp_to_str(filter, arg);
2195
2196 default:
2197
2198 return NULL;
2199 }
2200
2201 }
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212 char *
2213 tep_filter_make_string(struct tep_event_filter *filter, int event_id)
2214 {
2215 struct tep_filter_type *filter_type;
2216
2217 if (!filter->filters)
2218 return NULL;
2219
2220 filter_type = find_filter_type(filter, event_id);
2221
2222 if (!filter_type)
2223 return NULL;
2224
2225 return arg_to_str(filter, filter_type->filter);
2226 }
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237 int tep_filter_compare(struct tep_event_filter *filter1, struct tep_event_filter *filter2)
2238 {
2239 struct tep_filter_type *filter_type1;
2240 struct tep_filter_type *filter_type2;
2241 char *str1, *str2;
2242 int result;
2243 int i;
2244
2245
2246 if (filter1->filters != filter2->filters)
2247 return 0;
2248 if (!filter1->filters && !filter2->filters)
2249 return 1;
2250
2251
2252
2253
2254
2255 for (i = 0; i < filter1->filters; i++) {
2256 filter_type1 = &filter1->event_filters[i];
2257 filter_type2 = find_filter_type(filter2, filter_type1->event_id);
2258 if (!filter_type2)
2259 break;
2260 if (filter_type1->filter->type != filter_type2->filter->type)
2261 break;
2262
2263 str1 = arg_to_str(filter1, filter_type1->filter);
2264 str2 = arg_to_str(filter2, filter_type2->filter);
2265 if (str1 && str2)
2266 result = strcmp(str1, str2) != 0;
2267 else
2268
2269 result = 1;
2270
2271 free(str1);
2272 free(str2);
2273 if (result)
2274 break;
2275 }
2276
2277 if (i < filter1->filters)
2278 return 0;
2279 return 1;
2280 }
2281