parse-filter.c (49523B)
1// SPDX-License-Identifier: LGPL-2.1 2/* 3 * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> 4 * 5 */ 6#include <stdio.h> 7#include <stdlib.h> 8#include <string.h> 9#include <stdarg.h> 10#include <errno.h> 11#include <sys/types.h> 12 13#include "event-parse.h" 14#include "event-parse-local.h" 15#include "event-utils.h" 16 17#define COMM "COMM" 18#define CPU "CPU" 19 20static struct tep_format_field comm = { 21 .name = "COMM", 22}; 23 24static struct tep_format_field cpu = { 25 .name = "CPU", 26}; 27 28struct event_list { 29 struct event_list *next; 30 struct tep_event *event; 31}; 32 33static void show_error(char *error_buf, const char *fmt, ...) 34{ 35 unsigned long long index; 36 const char *input; 37 va_list ap; 38 int len; 39 int i; 40 41 input = get_input_buf(); 42 index = get_input_buf_ptr(); 43 len = input ? strlen(input) : 0; 44 45 if (len) { 46 strcpy(error_buf, input); 47 error_buf[len] = '\n'; 48 for (i = 1; i < len && i < index; i++) 49 error_buf[len+i] = ' '; 50 error_buf[len + i] = '^'; 51 error_buf[len + i + 1] = '\n'; 52 len += i+2; 53 } 54 55 va_start(ap, fmt); 56 vsnprintf(error_buf + len, TEP_FILTER_ERROR_BUFSZ - len, fmt, ap); 57 va_end(ap); 58} 59 60static enum tep_event_type filter_read_token(char **tok) 61{ 62 enum tep_event_type type; 63 char *token = NULL; 64 65 do { 66 free_token(token); 67 type = read_token(&token); 68 } while (type == TEP_EVENT_NEWLINE || type == TEP_EVENT_SPACE); 69 70 /* If token is = or ! check to see if the next char is ~ */ 71 if (token && 72 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) && 73 peek_char() == '~') { 74 /* append it */ 75 *tok = malloc(3); 76 if (*tok == NULL) { 77 free_token(token); 78 return TEP_EVENT_ERROR; 79 } 80 sprintf(*tok, "%c%c", *token, '~'); 81 free_token(token); 82 /* Now remove the '~' from the buffer */ 83 read_token(&token); 84 free_token(token); 85 } else 86 *tok = token; 87 88 return type; 89} 90 91static int filter_cmp(const void *a, const void *b) 92{ 93 const struct tep_filter_type *ea = a; 94 const struct tep_filter_type *eb = b; 95 96 if (ea->event_id < eb->event_id) 97 return -1; 98 99 if (ea->event_id > eb->event_id) 100 return 1; 101 102 return 0; 103} 104 105static struct tep_filter_type * 106find_filter_type(struct tep_event_filter *filter, int id) 107{ 108 struct tep_filter_type *filter_type; 109 struct tep_filter_type key; 110 111 key.event_id = id; 112 113 filter_type = bsearch(&key, filter->event_filters, 114 filter->filters, 115 sizeof(*filter->event_filters), 116 filter_cmp); 117 118 return filter_type; 119} 120 121static struct tep_filter_type * 122add_filter_type(struct tep_event_filter *filter, int id) 123{ 124 struct tep_filter_type *filter_type; 125 int i; 126 127 filter_type = find_filter_type(filter, id); 128 if (filter_type) 129 return filter_type; 130 131 filter_type = realloc(filter->event_filters, 132 sizeof(*filter->event_filters) * 133 (filter->filters + 1)); 134 if (!filter_type) 135 return NULL; 136 137 filter->event_filters = filter_type; 138 139 for (i = 0; i < filter->filters; i++) { 140 if (filter->event_filters[i].event_id > id) 141 break; 142 } 143 144 if (i < filter->filters) 145 memmove(&filter->event_filters[i+1], 146 &filter->event_filters[i], 147 sizeof(*filter->event_filters) * 148 (filter->filters - i)); 149 150 filter_type = &filter->event_filters[i]; 151 filter_type->event_id = id; 152 filter_type->event = tep_find_event(filter->tep, id); 153 filter_type->filter = NULL; 154 155 filter->filters++; 156 157 return filter_type; 158} 159 160/** 161 * tep_filter_alloc - create a new event filter 162 * @tep: The tep that this filter is associated with 163 */ 164struct tep_event_filter *tep_filter_alloc(struct tep_handle *tep) 165{ 166 struct tep_event_filter *filter; 167 168 filter = malloc(sizeof(*filter)); 169 if (filter == NULL) 170 return NULL; 171 172 memset(filter, 0, sizeof(*filter)); 173 filter->tep = tep; 174 tep_ref(tep); 175 176 return filter; 177} 178 179static struct tep_filter_arg *allocate_arg(void) 180{ 181 return calloc(1, sizeof(struct tep_filter_arg)); 182} 183 184static void free_arg(struct tep_filter_arg *arg) 185{ 186 if (!arg) 187 return; 188 189 switch (arg->type) { 190 case TEP_FILTER_ARG_NONE: 191 case TEP_FILTER_ARG_BOOLEAN: 192 break; 193 194 case TEP_FILTER_ARG_NUM: 195 free_arg(arg->num.left); 196 free_arg(arg->num.right); 197 break; 198 199 case TEP_FILTER_ARG_EXP: 200 free_arg(arg->exp.left); 201 free_arg(arg->exp.right); 202 break; 203 204 case TEP_FILTER_ARG_STR: 205 free(arg->str.val); 206 regfree(&arg->str.reg); 207 free(arg->str.buffer); 208 break; 209 210 case TEP_FILTER_ARG_VALUE: 211 if (arg->value.type == TEP_FILTER_STRING || 212 arg->value.type == TEP_FILTER_CHAR) 213 free(arg->value.str); 214 break; 215 216 case TEP_FILTER_ARG_OP: 217 free_arg(arg->op.left); 218 free_arg(arg->op.right); 219 default: 220 break; 221 } 222 223 free(arg); 224} 225 226static int add_event(struct event_list **events, 227 struct tep_event *event) 228{ 229 struct event_list *list; 230 231 list = malloc(sizeof(*list)); 232 if (list == NULL) 233 return -1; 234 235 list->next = *events; 236 *events = list; 237 list->event = event; 238 return 0; 239} 240 241static int event_match(struct tep_event *event, 242 regex_t *sreg, regex_t *ereg) 243{ 244 if (sreg) { 245 return !regexec(sreg, event->system, 0, NULL, 0) && 246 !regexec(ereg, event->name, 0, NULL, 0); 247 } 248 249 return !regexec(ereg, event->system, 0, NULL, 0) || 250 !regexec(ereg, event->name, 0, NULL, 0); 251} 252 253static enum tep_errno 254find_event(struct tep_handle *tep, struct event_list **events, 255 char *sys_name, char *event_name) 256{ 257 struct tep_event *event; 258 regex_t ereg; 259 regex_t sreg; 260 int match = 0; 261 int fail = 0; 262 char *reg; 263 int ret; 264 int i; 265 266 if (!event_name) { 267 /* if no name is given, then swap sys and name */ 268 event_name = sys_name; 269 sys_name = NULL; 270 } 271 272 ret = asprintf(®, "^%s$", event_name); 273 if (ret < 0) 274 return TEP_ERRNO__MEM_ALLOC_FAILED; 275 276 ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB); 277 free(reg); 278 279 if (ret) 280 return TEP_ERRNO__INVALID_EVENT_NAME; 281 282 if (sys_name) { 283 ret = asprintf(®, "^%s$", sys_name); 284 if (ret < 0) { 285 regfree(&ereg); 286 return TEP_ERRNO__MEM_ALLOC_FAILED; 287 } 288 289 ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB); 290 free(reg); 291 if (ret) { 292 regfree(&ereg); 293 return TEP_ERRNO__INVALID_EVENT_NAME; 294 } 295 } 296 297 for (i = 0; i < tep->nr_events; i++) { 298 event = tep->events[i]; 299 if (event_match(event, sys_name ? &sreg : NULL, &ereg)) { 300 match = 1; 301 if (add_event(events, event) < 0) { 302 fail = 1; 303 break; 304 } 305 } 306 } 307 308 regfree(&ereg); 309 if (sys_name) 310 regfree(&sreg); 311 312 if (!match) 313 return TEP_ERRNO__EVENT_NOT_FOUND; 314 if (fail) 315 return TEP_ERRNO__MEM_ALLOC_FAILED; 316 317 return 0; 318} 319 320static void free_events(struct event_list *events) 321{ 322 struct event_list *event; 323 324 while (events) { 325 event = events; 326 events = events->next; 327 free(event); 328 } 329} 330 331static enum tep_errno 332create_arg_item(struct tep_event *event, const char *token, 333 enum tep_event_type type, struct tep_filter_arg **parg, char *error_str) 334{ 335 struct tep_format_field *field; 336 struct tep_filter_arg *arg; 337 338 arg = allocate_arg(); 339 if (arg == NULL) { 340 show_error(error_str, "failed to allocate filter arg"); 341 return TEP_ERRNO__MEM_ALLOC_FAILED; 342 } 343 344 switch (type) { 345 346 case TEP_EVENT_SQUOTE: 347 case TEP_EVENT_DQUOTE: 348 arg->type = TEP_FILTER_ARG_VALUE; 349 arg->value.type = 350 type == TEP_EVENT_DQUOTE ? TEP_FILTER_STRING : TEP_FILTER_CHAR; 351 arg->value.str = strdup(token); 352 if (!arg->value.str) { 353 free_arg(arg); 354 show_error(error_str, "failed to allocate string filter arg"); 355 return TEP_ERRNO__MEM_ALLOC_FAILED; 356 } 357 break; 358 case TEP_EVENT_ITEM: 359 /* if it is a number, then convert it */ 360 if (isdigit(token[0])) { 361 arg->type = TEP_FILTER_ARG_VALUE; 362 arg->value.type = TEP_FILTER_NUMBER; 363 arg->value.val = strtoull(token, NULL, 0); 364 break; 365 } 366 /* Consider this a field */ 367 field = tep_find_any_field(event, token); 368 if (!field) { 369 /* If token is 'COMM' or 'CPU' then it is special */ 370 if (strcmp(token, COMM) == 0) { 371 field = &comm; 372 } else if (strcmp(token, CPU) == 0) { 373 field = &cpu; 374 } else { 375 /* not a field, Make it false */ 376 arg->type = TEP_FILTER_ARG_BOOLEAN; 377 arg->boolean.value = TEP_FILTER_FALSE; 378 break; 379 } 380 } 381 arg->type = TEP_FILTER_ARG_FIELD; 382 arg->field.field = field; 383 break; 384 default: 385 free_arg(arg); 386 show_error(error_str, "expected a value but found %s", token); 387 return TEP_ERRNO__UNEXPECTED_TYPE; 388 } 389 *parg = arg; 390 return 0; 391} 392 393static struct tep_filter_arg * 394create_arg_op(enum tep_filter_op_type btype) 395{ 396 struct tep_filter_arg *arg; 397 398 arg = allocate_arg(); 399 if (!arg) 400 return NULL; 401 402 arg->type = TEP_FILTER_ARG_OP; 403 arg->op.type = btype; 404 405 return arg; 406} 407 408static struct tep_filter_arg * 409create_arg_exp(enum tep_filter_exp_type etype) 410{ 411 struct tep_filter_arg *arg; 412 413 arg = allocate_arg(); 414 if (!arg) 415 return NULL; 416 417 arg->type = TEP_FILTER_ARG_EXP; 418 arg->exp.type = etype; 419 420 return arg; 421} 422 423static struct tep_filter_arg * 424create_arg_cmp(enum tep_filter_cmp_type ctype) 425{ 426 struct tep_filter_arg *arg; 427 428 arg = allocate_arg(); 429 if (!arg) 430 return NULL; 431 432 /* Use NUM and change if necessary */ 433 arg->type = TEP_FILTER_ARG_NUM; 434 arg->num.type = ctype; 435 436 return arg; 437} 438 439static enum tep_errno 440add_right(struct tep_filter_arg *op, struct tep_filter_arg *arg, char *error_str) 441{ 442 struct tep_filter_arg *left; 443 char *str; 444 int op_type; 445 int ret; 446 447 switch (op->type) { 448 case TEP_FILTER_ARG_EXP: 449 if (op->exp.right) 450 goto out_fail; 451 op->exp.right = arg; 452 break; 453 454 case TEP_FILTER_ARG_OP: 455 if (op->op.right) 456 goto out_fail; 457 op->op.right = arg; 458 break; 459 460 case TEP_FILTER_ARG_NUM: 461 if (op->op.right) 462 goto out_fail; 463 /* 464 * The arg must be num, str, or field 465 */ 466 switch (arg->type) { 467 case TEP_FILTER_ARG_VALUE: 468 case TEP_FILTER_ARG_FIELD: 469 break; 470 default: 471 show_error(error_str, "Illegal rvalue"); 472 return TEP_ERRNO__ILLEGAL_RVALUE; 473 } 474 475 /* 476 * Depending on the type, we may need to 477 * convert this to a string or regex. 478 */ 479 switch (arg->value.type) { 480 case TEP_FILTER_CHAR: 481 /* 482 * A char should be converted to number if 483 * the string is 1 byte, and the compare 484 * is not a REGEX. 485 */ 486 if (strlen(arg->value.str) == 1 && 487 op->num.type != TEP_FILTER_CMP_REGEX && 488 op->num.type != TEP_FILTER_CMP_NOT_REGEX) { 489 arg->value.type = TEP_FILTER_NUMBER; 490 goto do_int; 491 } 492 /* fall through */ 493 case TEP_FILTER_STRING: 494 495 /* convert op to a string arg */ 496 op_type = op->num.type; 497 left = op->num.left; 498 str = arg->value.str; 499 500 /* reset the op for the new field */ 501 memset(op, 0, sizeof(*op)); 502 503 /* 504 * If left arg was a field not found then 505 * NULL the entire op. 506 */ 507 if (left->type == TEP_FILTER_ARG_BOOLEAN) { 508 free_arg(left); 509 free_arg(arg); 510 op->type = TEP_FILTER_ARG_BOOLEAN; 511 op->boolean.value = TEP_FILTER_FALSE; 512 break; 513 } 514 515 /* Left arg must be a field */ 516 if (left->type != TEP_FILTER_ARG_FIELD) { 517 show_error(error_str, 518 "Illegal lvalue for string comparison"); 519 return TEP_ERRNO__ILLEGAL_LVALUE; 520 } 521 522 /* Make sure this is a valid string compare */ 523 switch (op_type) { 524 case TEP_FILTER_CMP_EQ: 525 op_type = TEP_FILTER_CMP_MATCH; 526 break; 527 case TEP_FILTER_CMP_NE: 528 op_type = TEP_FILTER_CMP_NOT_MATCH; 529 break; 530 531 case TEP_FILTER_CMP_REGEX: 532 case TEP_FILTER_CMP_NOT_REGEX: 533 ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB); 534 if (ret) { 535 show_error(error_str, 536 "RegEx '%s' did not compute", 537 str); 538 return TEP_ERRNO__INVALID_REGEX; 539 } 540 break; 541 default: 542 show_error(error_str, 543 "Illegal comparison for string"); 544 return TEP_ERRNO__ILLEGAL_STRING_CMP; 545 } 546 547 op->type = TEP_FILTER_ARG_STR; 548 op->str.type = op_type; 549 op->str.field = left->field.field; 550 op->str.val = strdup(str); 551 if (!op->str.val) { 552 show_error(error_str, "Failed to allocate string filter"); 553 return TEP_ERRNO__MEM_ALLOC_FAILED; 554 } 555 /* 556 * Need a buffer to copy data for tests 557 */ 558 op->str.buffer = malloc(op->str.field->size + 1); 559 if (!op->str.buffer) { 560 show_error(error_str, "Failed to allocate string filter"); 561 return TEP_ERRNO__MEM_ALLOC_FAILED; 562 } 563 /* Null terminate this buffer */ 564 op->str.buffer[op->str.field->size] = 0; 565 566 /* We no longer have left or right args */ 567 free_arg(arg); 568 free_arg(left); 569 570 break; 571 572 case TEP_FILTER_NUMBER: 573 574 do_int: 575 switch (op->num.type) { 576 case TEP_FILTER_CMP_REGEX: 577 case TEP_FILTER_CMP_NOT_REGEX: 578 show_error(error_str, 579 "Op not allowed with integers"); 580 return TEP_ERRNO__ILLEGAL_INTEGER_CMP; 581 582 default: 583 break; 584 } 585 586 /* numeric compare */ 587 op->num.right = arg; 588 break; 589 default: 590 goto out_fail; 591 } 592 break; 593 default: 594 goto out_fail; 595 } 596 597 return 0; 598 599 out_fail: 600 show_error(error_str, "Syntax error"); 601 return TEP_ERRNO__SYNTAX_ERROR; 602} 603 604static struct tep_filter_arg * 605rotate_op_right(struct tep_filter_arg *a, struct tep_filter_arg *b) 606{ 607 struct tep_filter_arg *arg; 608 609 arg = a->op.right; 610 a->op.right = b; 611 return arg; 612} 613 614static enum tep_errno add_left(struct tep_filter_arg *op, struct tep_filter_arg *arg) 615{ 616 switch (op->type) { 617 case TEP_FILTER_ARG_EXP: 618 if (arg->type == TEP_FILTER_ARG_OP) 619 arg = rotate_op_right(arg, op); 620 op->exp.left = arg; 621 break; 622 623 case TEP_FILTER_ARG_OP: 624 op->op.left = arg; 625 break; 626 case TEP_FILTER_ARG_NUM: 627 if (arg->type == TEP_FILTER_ARG_OP) 628 arg = rotate_op_right(arg, op); 629 630 /* left arg of compares must be a field */ 631 if (arg->type != TEP_FILTER_ARG_FIELD && 632 arg->type != TEP_FILTER_ARG_BOOLEAN) 633 return TEP_ERRNO__INVALID_ARG_TYPE; 634 op->num.left = arg; 635 break; 636 default: 637 return TEP_ERRNO__INVALID_ARG_TYPE; 638 } 639 return 0; 640} 641 642enum op_type { 643 OP_NONE, 644 OP_BOOL, 645 OP_NOT, 646 OP_EXP, 647 OP_CMP, 648}; 649 650static enum op_type process_op(const char *token, 651 enum tep_filter_op_type *btype, 652 enum tep_filter_cmp_type *ctype, 653 enum tep_filter_exp_type *etype) 654{ 655 *btype = TEP_FILTER_OP_NOT; 656 *etype = TEP_FILTER_EXP_NONE; 657 *ctype = TEP_FILTER_CMP_NONE; 658 659 if (strcmp(token, "&&") == 0) 660 *btype = TEP_FILTER_OP_AND; 661 else if (strcmp(token, "||") == 0) 662 *btype = TEP_FILTER_OP_OR; 663 else if (strcmp(token, "!") == 0) 664 return OP_NOT; 665 666 if (*btype != TEP_FILTER_OP_NOT) 667 return OP_BOOL; 668 669 /* Check for value expressions */ 670 if (strcmp(token, "+") == 0) { 671 *etype = TEP_FILTER_EXP_ADD; 672 } else if (strcmp(token, "-") == 0) { 673 *etype = TEP_FILTER_EXP_SUB; 674 } else if (strcmp(token, "*") == 0) { 675 *etype = TEP_FILTER_EXP_MUL; 676 } else if (strcmp(token, "/") == 0) { 677 *etype = TEP_FILTER_EXP_DIV; 678 } else if (strcmp(token, "%") == 0) { 679 *etype = TEP_FILTER_EXP_MOD; 680 } else if (strcmp(token, ">>") == 0) { 681 *etype = TEP_FILTER_EXP_RSHIFT; 682 } else if (strcmp(token, "<<") == 0) { 683 *etype = TEP_FILTER_EXP_LSHIFT; 684 } else if (strcmp(token, "&") == 0) { 685 *etype = TEP_FILTER_EXP_AND; 686 } else if (strcmp(token, "|") == 0) { 687 *etype = TEP_FILTER_EXP_OR; 688 } else if (strcmp(token, "^") == 0) { 689 *etype = TEP_FILTER_EXP_XOR; 690 } else if (strcmp(token, "~") == 0) 691 *etype = TEP_FILTER_EXP_NOT; 692 693 if (*etype != TEP_FILTER_EXP_NONE) 694 return OP_EXP; 695 696 /* Check for compares */ 697 if (strcmp(token, "==") == 0) 698 *ctype = TEP_FILTER_CMP_EQ; 699 else if (strcmp(token, "!=") == 0) 700 *ctype = TEP_FILTER_CMP_NE; 701 else if (strcmp(token, "<") == 0) 702 *ctype = TEP_FILTER_CMP_LT; 703 else if (strcmp(token, ">") == 0) 704 *ctype = TEP_FILTER_CMP_GT; 705 else if (strcmp(token, "<=") == 0) 706 *ctype = TEP_FILTER_CMP_LE; 707 else if (strcmp(token, ">=") == 0) 708 *ctype = TEP_FILTER_CMP_GE; 709 else if (strcmp(token, "=~") == 0) 710 *ctype = TEP_FILTER_CMP_REGEX; 711 else if (strcmp(token, "!~") == 0) 712 *ctype = TEP_FILTER_CMP_NOT_REGEX; 713 else 714 return OP_NONE; 715 716 return OP_CMP; 717} 718 719static int check_op_done(struct tep_filter_arg *arg) 720{ 721 switch (arg->type) { 722 case TEP_FILTER_ARG_EXP: 723 return arg->exp.right != NULL; 724 725 case TEP_FILTER_ARG_OP: 726 return arg->op.right != NULL; 727 728 case TEP_FILTER_ARG_NUM: 729 return arg->num.right != NULL; 730 731 case TEP_FILTER_ARG_STR: 732 /* A string conversion is always done */ 733 return 1; 734 735 case TEP_FILTER_ARG_BOOLEAN: 736 /* field not found, is ok */ 737 return 1; 738 739 default: 740 return 0; 741 } 742} 743 744enum filter_vals { 745 FILTER_VAL_NORM, 746 FILTER_VAL_FALSE, 747 FILTER_VAL_TRUE, 748}; 749 750static enum tep_errno 751reparent_op_arg(struct tep_filter_arg *parent, struct tep_filter_arg *old_child, 752 struct tep_filter_arg *arg, char *error_str) 753{ 754 struct tep_filter_arg *other_child; 755 struct tep_filter_arg **ptr; 756 757 if (parent->type != TEP_FILTER_ARG_OP && 758 arg->type != TEP_FILTER_ARG_OP) { 759 show_error(error_str, "can not reparent other than OP"); 760 return TEP_ERRNO__REPARENT_NOT_OP; 761 } 762 763 /* Get the sibling */ 764 if (old_child->op.right == arg) { 765 ptr = &old_child->op.right; 766 other_child = old_child->op.left; 767 } else if (old_child->op.left == arg) { 768 ptr = &old_child->op.left; 769 other_child = old_child->op.right; 770 } else { 771 show_error(error_str, "Error in reparent op, find other child"); 772 return TEP_ERRNO__REPARENT_FAILED; 773 } 774 775 /* Detach arg from old_child */ 776 *ptr = NULL; 777 778 /* Check for root */ 779 if (parent == old_child) { 780 free_arg(other_child); 781 *parent = *arg; 782 /* Free arg without recussion */ 783 free(arg); 784 return 0; 785 } 786 787 if (parent->op.right == old_child) 788 ptr = &parent->op.right; 789 else if (parent->op.left == old_child) 790 ptr = &parent->op.left; 791 else { 792 show_error(error_str, "Error in reparent op"); 793 return TEP_ERRNO__REPARENT_FAILED; 794 } 795 796 *ptr = arg; 797 798 free_arg(old_child); 799 return 0; 800} 801 802/* Returns either filter_vals (success) or tep_errno (failfure) */ 803static int test_arg(struct tep_filter_arg *parent, struct tep_filter_arg *arg, 804 char *error_str) 805{ 806 int lval, rval; 807 808 switch (arg->type) { 809 810 /* bad case */ 811 case TEP_FILTER_ARG_BOOLEAN: 812 return FILTER_VAL_FALSE + arg->boolean.value; 813 814 /* good cases: */ 815 case TEP_FILTER_ARG_STR: 816 case TEP_FILTER_ARG_VALUE: 817 case TEP_FILTER_ARG_FIELD: 818 return FILTER_VAL_NORM; 819 820 case TEP_FILTER_ARG_EXP: 821 lval = test_arg(arg, arg->exp.left, error_str); 822 if (lval != FILTER_VAL_NORM) 823 return lval; 824 rval = test_arg(arg, arg->exp.right, error_str); 825 if (rval != FILTER_VAL_NORM) 826 return rval; 827 return FILTER_VAL_NORM; 828 829 case TEP_FILTER_ARG_NUM: 830 lval = test_arg(arg, arg->num.left, error_str); 831 if (lval != FILTER_VAL_NORM) 832 return lval; 833 rval = test_arg(arg, arg->num.right, error_str); 834 if (rval != FILTER_VAL_NORM) 835 return rval; 836 return FILTER_VAL_NORM; 837 838 case TEP_FILTER_ARG_OP: 839 if (arg->op.type != TEP_FILTER_OP_NOT) { 840 lval = test_arg(arg, arg->op.left, error_str); 841 switch (lval) { 842 case FILTER_VAL_NORM: 843 break; 844 case FILTER_VAL_TRUE: 845 if (arg->op.type == TEP_FILTER_OP_OR) 846 return FILTER_VAL_TRUE; 847 rval = test_arg(arg, arg->op.right, error_str); 848 if (rval != FILTER_VAL_NORM) 849 return rval; 850 851 return reparent_op_arg(parent, arg, arg->op.right, 852 error_str); 853 854 case FILTER_VAL_FALSE: 855 if (arg->op.type == TEP_FILTER_OP_AND) 856 return FILTER_VAL_FALSE; 857 rval = test_arg(arg, arg->op.right, error_str); 858 if (rval != FILTER_VAL_NORM) 859 return rval; 860 861 return reparent_op_arg(parent, arg, arg->op.right, 862 error_str); 863 864 default: 865 return lval; 866 } 867 } 868 869 rval = test_arg(arg, arg->op.right, error_str); 870 switch (rval) { 871 case FILTER_VAL_NORM: 872 default: 873 break; 874 875 case FILTER_VAL_TRUE: 876 if (arg->op.type == TEP_FILTER_OP_OR) 877 return FILTER_VAL_TRUE; 878 if (arg->op.type == TEP_FILTER_OP_NOT) 879 return FILTER_VAL_FALSE; 880 881 return reparent_op_arg(parent, arg, arg->op.left, 882 error_str); 883 884 case FILTER_VAL_FALSE: 885 if (arg->op.type == TEP_FILTER_OP_AND) 886 return FILTER_VAL_FALSE; 887 if (arg->op.type == TEP_FILTER_OP_NOT) 888 return FILTER_VAL_TRUE; 889 890 return reparent_op_arg(parent, arg, arg->op.left, 891 error_str); 892 } 893 894 return rval; 895 default: 896 show_error(error_str, "bad arg in filter tree"); 897 return TEP_ERRNO__BAD_FILTER_ARG; 898 } 899 return FILTER_VAL_NORM; 900} 901 902/* Remove any unknown event fields */ 903static int collapse_tree(struct tep_filter_arg *arg, 904 struct tep_filter_arg **arg_collapsed, char *error_str) 905{ 906 int ret; 907 908 ret = test_arg(arg, arg, error_str); 909 switch (ret) { 910 case FILTER_VAL_NORM: 911 break; 912 913 case FILTER_VAL_TRUE: 914 case FILTER_VAL_FALSE: 915 free_arg(arg); 916 arg = allocate_arg(); 917 if (arg) { 918 arg->type = TEP_FILTER_ARG_BOOLEAN; 919 arg->boolean.value = ret == FILTER_VAL_TRUE; 920 } else { 921 show_error(error_str, "Failed to allocate filter arg"); 922 ret = TEP_ERRNO__MEM_ALLOC_FAILED; 923 } 924 break; 925 926 default: 927 /* test_arg() already set the error_str */ 928 free_arg(arg); 929 arg = NULL; 930 break; 931 } 932 933 *arg_collapsed = arg; 934 return ret; 935} 936 937static enum tep_errno 938process_filter(struct tep_event *event, struct tep_filter_arg **parg, 939 char *error_str, int not) 940{ 941 enum tep_event_type type; 942 char *token = NULL; 943 struct tep_filter_arg *current_op = NULL; 944 struct tep_filter_arg *current_exp = NULL; 945 struct tep_filter_arg *left_item = NULL; 946 struct tep_filter_arg *arg = NULL; 947 enum op_type op_type; 948 enum tep_filter_op_type btype; 949 enum tep_filter_exp_type etype; 950 enum tep_filter_cmp_type ctype; 951 enum tep_errno ret; 952 953 *parg = NULL; 954 955 do { 956 free(token); 957 type = filter_read_token(&token); 958 switch (type) { 959 case TEP_EVENT_SQUOTE: 960 case TEP_EVENT_DQUOTE: 961 case TEP_EVENT_ITEM: 962 ret = create_arg_item(event, token, type, &arg, error_str); 963 if (ret < 0) 964 goto fail; 965 if (!left_item) 966 left_item = arg; 967 else if (current_exp) { 968 ret = add_right(current_exp, arg, error_str); 969 if (ret < 0) 970 goto fail; 971 left_item = NULL; 972 /* Not's only one one expression */ 973 if (not) { 974 arg = NULL; 975 if (current_op) 976 goto fail_syntax; 977 free(token); 978 *parg = current_exp; 979 return 0; 980 } 981 } else 982 goto fail_syntax; 983 arg = NULL; 984 break; 985 986 case TEP_EVENT_DELIM: 987 if (*token == ',') { 988 show_error(error_str, "Illegal token ','"); 989 ret = TEP_ERRNO__ILLEGAL_TOKEN; 990 goto fail; 991 } 992 993 if (*token == '(') { 994 if (left_item) { 995 show_error(error_str, 996 "Open paren can not come after item"); 997 ret = TEP_ERRNO__INVALID_PAREN; 998 goto fail; 999 } 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 /* A not wants just one expression */ 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 /* Make sure everything is finished at this level */ 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 /* All expect a left arg except for NOT */ 1057 switch (op_type) { 1058 case OP_BOOL: 1059 /* Logic ops need a left expression */ 1060 if (!current_exp && !current_op) 1061 goto fail_syntax; 1062 /* fall through */ 1063 case OP_NOT: 1064 /* logic only processes ops and exp */ 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 /* collapse_tree() may free current_op, and updates parg accordingly */ 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 1177static enum tep_errno 1178process_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 /* If parg is NULL, then make it into FALSE */ 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 1202static enum tep_errno 1203filter_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 /* just add a TRUE arg */ 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 1238static void filter_init_error_buf(struct tep_event_filter *filter) 1239{ 1240 /* clear buffer to reset show error */ 1241 init_input_buf("", 0); 1242 filter->error_buffer[0] = '\0'; 1243} 1244 1245/** 1246 * tep_filter_add_filter_str - add a new filter 1247 * @filter: the event filter to add to 1248 * @filter_str: the filter string that contains the filter 1249 * 1250 * Returns 0 if the filter was successfully added or a 1251 * negative error code. Use tep_filter_strerror() to see 1252 * actual error message in case of error. 1253 */ 1254enum 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; /* TEP_ERRNO__SUCCESS */ 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 /* This can only happen when events is NULL, but still */ 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 /* This can only happen when events is NULL, but still */ 1307 free_events(events); 1308 free(this_event); 1309 return TEP_ERRNO__FILTER_NOT_FOUND; 1310 } 1311 1312 /* Find this event */ 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 /* Skip the ':' */ 1323 if (filter_start) 1324 filter_start++; 1325 1326 /* filter starts here */ 1327 for (event = events; event; event = event->next) { 1328 ret = filter_event(filter, event->event, filter_start, 1329 filter->error_buffer); 1330 /* Failures are returned if a parse error happened */ 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 1349static void free_filter_type(struct tep_filter_type *filter_type) 1350{ 1351 free_arg(filter_type->filter); 1352} 1353 1354/** 1355 * tep_filter_strerror - fill error message in a buffer 1356 * @filter: the event filter contains error 1357 * @err: the error code 1358 * @buf: the buffer to be filled in 1359 * @buflen: the size of the buffer 1360 * 1361 * Returns 0 if message was filled successfully, -1 if error 1362 */ 1363int 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 * tep_filter_remove_event - remove a filter for an event 1382 * @filter: the event filter to remove from 1383 * @event_id: the event to remove a filter for 1384 * 1385 * Removes the filter saved for an event defined by @event_id 1386 * from the @filter. 1387 * 1388 * Returns 1: if an event was removed 1389 * 0: if the event was not found 1390 */ 1391int 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 /* The filter_type points into the event_filters array */ 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 * tep_filter_reset - clear all filters in a filter 1422 * @filter: the event filter to reset 1423 * 1424 * Removes all filters from a filter and resets it. 1425 */ 1426void 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 1438void 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 1447static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg); 1448 1449static 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 /* Can't assume that the tep's are the same */ 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 /* Add trivial event */ 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 * tep_filter_copy - copy a filter using another filter 1505 * @dest - the filter to copy to 1506 * @source - the filter to copy from 1507 * 1508 * Returns 0 on success and -1 if not all filters were copied 1509 */ 1510int 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 1524static int test_filter(struct tep_event *event, struct tep_filter_arg *arg, 1525 struct tep_record *record, enum tep_errno *err); 1526 1527static const char * 1528get_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 1538static unsigned long long 1539get_value(struct tep_event *event, 1540 struct tep_format_field *field, struct tep_record *record) 1541{ 1542 unsigned long long val; 1543 1544 /* Handle our dummy "comm" field */ 1545 if (field == &comm) { 1546 const char *name; 1547 1548 name = get_comm(event, record); 1549 return (unsigned long)name; 1550 } 1551 1552 /* Handle our dummy "cpu" field */ 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 1574static unsigned long long 1575get_arg_value(struct tep_event *event, struct tep_filter_arg *arg, 1576 struct tep_record *record, enum tep_errno *err); 1577 1578static unsigned long long 1579get_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 * There was an error, no need to process anymore. 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 1633static unsigned long long 1634get_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 1658static 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 * There was an error, no need to process anymore. 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 1699static 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 /* If the field is not a string convert it */ 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 * We need to copy the data since we can't be sure the field 1724 * is null terminated. 1725 */ 1726 if (*(val + size - 1)) { 1727 /* copy it */ 1728 memcpy(arg->str.buffer, val, arg->str.field->size); 1729 /* the buffer is already NULL terminated */ 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 /* convert to a kernel symbol */ 1740 val = tep_find_function(tep, addr); 1741 1742 if (val == NULL) { 1743 /* just use the hex of the string name */ 1744 snprintf(hex, 64, "0x%llx", addr); 1745 val = hex; 1746 } 1747 } 1748 1749 return val; 1750} 1751 1752static 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 /* Returns zero on match */ 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 1783static 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 1805static 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 * There was an error, no need to process anymore. 1811 */ 1812 return 0; 1813 } 1814 1815 switch (arg->type) { 1816 case TEP_FILTER_ARG_BOOLEAN: 1817 /* easy case */ 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 * Expressions, fields and values evaluate 1834 * to true if they return non zero 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 * tep_event_filtered - return true if event has filter 1847 * @filter: filter struct with filter information 1848 * @event_id: event id to test if filter exists 1849 * 1850 * Returns 1 if filter found for @event_id 1851 * otherwise 0; 1852 */ 1853int 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 * tep_filter_match - test if a record matches a filter 1867 * @filter: filter struct with filter information 1868 * @record: the record to test against the filter 1869 * 1870 * Returns: match result or error code (prefixed with TEP_ERRNO__) 1871 * FILTER_MATCH - filter found for event and @record matches 1872 * FILTER_MISS - filter found for event and @record does not match 1873 * FILTER_NOT_FOUND - no filter found for @record's event 1874 * NO_FILTER - if no filters exist 1875 * otherwise - error occurred during test 1876 */ 1877enum 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 1904static 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 /* fall through */ 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 /* Try to consolidate boolean values */ 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 /* Just return left value */ 1942 str = left; 1943 left = NULL; 1944 break; 1945 } 1946 if (right_val >= 0) { 1947 /* just evaluate this. */ 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 /* Just return right value */ 1968 str = right; 1969 right = NULL; 1970 break; 1971 } 1972 /* The right value is meaningless */ 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 /* See if we can consolidate */ 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 /* just return the opposite */ 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 2012static 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 2022static char *field_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2023{ 2024 return strdup(arg->field.field->name); 2025} 2026 2027static 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; 2077out: 2078 free(lstr); 2079 free(rstr); 2080 2081 return str; 2082} 2083 2084static 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 /* fall through */ 2100 case TEP_FILTER_CMP_NE: 2101 if (!op) 2102 op = "!="; 2103 /* fall through */ 2104 case TEP_FILTER_CMP_GT: 2105 if (!op) 2106 op = ">"; 2107 /* fall through */ 2108 case TEP_FILTER_CMP_LT: 2109 if (!op) 2110 op = "<"; 2111 /* fall through */ 2112 case TEP_FILTER_CMP_GE: 2113 if (!op) 2114 op = ">="; 2115 /* fall through */ 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 2129out: 2130 free(lstr); 2131 free(rstr); 2132 return str; 2133} 2134 2135static 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 /* fall through */ 2144 case TEP_FILTER_CMP_NOT_MATCH: 2145 if (!op) 2146 op = "!="; 2147 /* fall through */ 2148 case TEP_FILTER_CMP_REGEX: 2149 if (!op) 2150 op = "=~"; 2151 /* fall through */ 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 2168static 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 * tep_filter_make_string - return a string showing the filter 2205 * @filter: filter struct with filter information 2206 * @event_id: the event id to return the filter string with 2207 * 2208 * Returns a string that displays the filter contents. 2209 * This string must be freed with free(str). 2210 * NULL is returned if no filter is found or allocation failed. 2211 */ 2212char * 2213tep_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 * tep_filter_compare - compare two filters and return if they are the same 2230 * @filter1: Filter to compare with @filter2 2231 * @filter2: Filter to compare with @filter1 2232 * 2233 * Returns: 2234 * 1 if the two filters hold the same content. 2235 * 0 if they do not. 2236 */ 2237int 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 /* Do the easy checks first */ 2246 if (filter1->filters != filter2->filters) 2247 return 0; 2248 if (!filter1->filters && !filter2->filters) 2249 return 1; 2250 2251 /* 2252 * Now take a look at each of the events to see if they have the same 2253 * filters to them. 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 /* The best way to compare complex filters is with strings */ 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 /* bail out if allocation fails */ 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