at v4.19-rc6 52 kB view raw
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-utils.h" 15 16#define COMM "COMM" 17#define CPU "CPU" 18 19static struct format_field comm = { 20 .name = "COMM", 21}; 22 23static struct format_field cpu = { 24 .name = "CPU", 25}; 26 27struct event_list { 28 struct event_list *next; 29 struct event_format *event; 30}; 31 32static void show_error(char *error_buf, const char *fmt, ...) 33{ 34 unsigned long long index; 35 const char *input; 36 va_list ap; 37 int len; 38 int i; 39 40 input = tep_get_input_buf(); 41 index = tep_get_input_buf_ptr(); 42 len = input ? strlen(input) : 0; 43 44 if (len) { 45 strcpy(error_buf, input); 46 error_buf[len] = '\n'; 47 for (i = 1; i < len && i < index; i++) 48 error_buf[len+i] = ' '; 49 error_buf[len + i] = '^'; 50 error_buf[len + i + 1] = '\n'; 51 len += i+2; 52 } 53 54 va_start(ap, fmt); 55 vsnprintf(error_buf + len, TEP_FILTER_ERROR_BUFSZ - len, fmt, ap); 56 va_end(ap); 57} 58 59static void free_token(char *token) 60{ 61 tep_free_token(token); 62} 63 64static enum event_type read_token(char **tok) 65{ 66 enum event_type type; 67 char *token = NULL; 68 69 do { 70 free_token(token); 71 type = tep_read_token(&token); 72 } while (type == EVENT_NEWLINE || type == EVENT_SPACE); 73 74 /* If token is = or ! check to see if the next char is ~ */ 75 if (token && 76 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) && 77 tep_peek_char() == '~') { 78 /* append it */ 79 *tok = malloc(3); 80 if (*tok == NULL) { 81 free_token(token); 82 return EVENT_ERROR; 83 } 84 sprintf(*tok, "%c%c", *token, '~'); 85 free_token(token); 86 /* Now remove the '~' from the buffer */ 87 tep_read_token(&token); 88 free_token(token); 89 } else 90 *tok = token; 91 92 return type; 93} 94 95static int filter_cmp(const void *a, const void *b) 96{ 97 const struct filter_type *ea = a; 98 const struct filter_type *eb = b; 99 100 if (ea->event_id < eb->event_id) 101 return -1; 102 103 if (ea->event_id > eb->event_id) 104 return 1; 105 106 return 0; 107} 108 109static struct filter_type * 110find_filter_type(struct event_filter *filter, int id) 111{ 112 struct filter_type *filter_type; 113 struct filter_type key; 114 115 key.event_id = id; 116 117 filter_type = bsearch(&key, filter->event_filters, 118 filter->filters, 119 sizeof(*filter->event_filters), 120 filter_cmp); 121 122 return filter_type; 123} 124 125static struct filter_type * 126add_filter_type(struct event_filter *filter, int id) 127{ 128 struct filter_type *filter_type; 129 int i; 130 131 filter_type = find_filter_type(filter, id); 132 if (filter_type) 133 return filter_type; 134 135 filter_type = realloc(filter->event_filters, 136 sizeof(*filter->event_filters) * 137 (filter->filters + 1)); 138 if (!filter_type) 139 return NULL; 140 141 filter->event_filters = filter_type; 142 143 for (i = 0; i < filter->filters; i++) { 144 if (filter->event_filters[i].event_id > id) 145 break; 146 } 147 148 if (i < filter->filters) 149 memmove(&filter->event_filters[i+1], 150 &filter->event_filters[i], 151 sizeof(*filter->event_filters) * 152 (filter->filters - i)); 153 154 filter_type = &filter->event_filters[i]; 155 filter_type->event_id = id; 156 filter_type->event = tep_find_event(filter->pevent, id); 157 filter_type->filter = NULL; 158 159 filter->filters++; 160 161 return filter_type; 162} 163 164/** 165 * tep_filter_alloc - create a new event filter 166 * @pevent: The pevent that this filter is associated with 167 */ 168struct event_filter *tep_filter_alloc(struct tep_handle *pevent) 169{ 170 struct event_filter *filter; 171 172 filter = malloc(sizeof(*filter)); 173 if (filter == NULL) 174 return NULL; 175 176 memset(filter, 0, sizeof(*filter)); 177 filter->pevent = pevent; 178 tep_ref(pevent); 179 180 return filter; 181} 182 183static struct filter_arg *allocate_arg(void) 184{ 185 return calloc(1, sizeof(struct filter_arg)); 186} 187 188static void free_arg(struct filter_arg *arg) 189{ 190 if (!arg) 191 return; 192 193 switch (arg->type) { 194 case FILTER_ARG_NONE: 195 case FILTER_ARG_BOOLEAN: 196 break; 197 198 case FILTER_ARG_NUM: 199 free_arg(arg->num.left); 200 free_arg(arg->num.right); 201 break; 202 203 case FILTER_ARG_EXP: 204 free_arg(arg->exp.left); 205 free_arg(arg->exp.right); 206 break; 207 208 case FILTER_ARG_STR: 209 free(arg->str.val); 210 regfree(&arg->str.reg); 211 free(arg->str.buffer); 212 break; 213 214 case FILTER_ARG_VALUE: 215 if (arg->value.type == FILTER_STRING || 216 arg->value.type == FILTER_CHAR) 217 free(arg->value.str); 218 break; 219 220 case FILTER_ARG_OP: 221 free_arg(arg->op.left); 222 free_arg(arg->op.right); 223 default: 224 break; 225 } 226 227 free(arg); 228} 229 230static int add_event(struct event_list **events, 231 struct event_format *event) 232{ 233 struct event_list *list; 234 235 list = malloc(sizeof(*list)); 236 if (list == NULL) 237 return -1; 238 239 list->next = *events; 240 *events = list; 241 list->event = event; 242 return 0; 243} 244 245static int event_match(struct event_format *event, 246 regex_t *sreg, regex_t *ereg) 247{ 248 if (sreg) { 249 return !regexec(sreg, event->system, 0, NULL, 0) && 250 !regexec(ereg, event->name, 0, NULL, 0); 251 } 252 253 return !regexec(ereg, event->system, 0, NULL, 0) || 254 !regexec(ereg, event->name, 0, NULL, 0); 255} 256 257static enum tep_errno 258find_event(struct tep_handle *pevent, struct event_list **events, 259 char *sys_name, char *event_name) 260{ 261 struct event_format *event; 262 regex_t ereg; 263 regex_t sreg; 264 int match = 0; 265 int fail = 0; 266 char *reg; 267 int ret; 268 int i; 269 270 if (!event_name) { 271 /* if no name is given, then swap sys and name */ 272 event_name = sys_name; 273 sys_name = NULL; 274 } 275 276 ret = asprintf(&reg, "^%s$", event_name); 277 if (ret < 0) 278 return TEP_ERRNO__MEM_ALLOC_FAILED; 279 280 ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB); 281 free(reg); 282 283 if (ret) 284 return TEP_ERRNO__INVALID_EVENT_NAME; 285 286 if (sys_name) { 287 ret = asprintf(&reg, "^%s$", sys_name); 288 if (ret < 0) { 289 regfree(&ereg); 290 return TEP_ERRNO__MEM_ALLOC_FAILED; 291 } 292 293 ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB); 294 free(reg); 295 if (ret) { 296 regfree(&ereg); 297 return TEP_ERRNO__INVALID_EVENT_NAME; 298 } 299 } 300 301 for (i = 0; i < pevent->nr_events; i++) { 302 event = pevent->events[i]; 303 if (event_match(event, sys_name ? &sreg : NULL, &ereg)) { 304 match = 1; 305 if (add_event(events, event) < 0) { 306 fail = 1; 307 break; 308 } 309 } 310 } 311 312 regfree(&ereg); 313 if (sys_name) 314 regfree(&sreg); 315 316 if (!match) 317 return TEP_ERRNO__EVENT_NOT_FOUND; 318 if (fail) 319 return TEP_ERRNO__MEM_ALLOC_FAILED; 320 321 return 0; 322} 323 324static void free_events(struct event_list *events) 325{ 326 struct event_list *event; 327 328 while (events) { 329 event = events; 330 events = events->next; 331 free(event); 332 } 333} 334 335static enum tep_errno 336create_arg_item(struct event_format *event, const char *token, 337 enum event_type type, struct filter_arg **parg, char *error_str) 338{ 339 struct format_field *field; 340 struct filter_arg *arg; 341 342 arg = allocate_arg(); 343 if (arg == NULL) { 344 show_error(error_str, "failed to allocate filter arg"); 345 return TEP_ERRNO__MEM_ALLOC_FAILED; 346 } 347 348 switch (type) { 349 350 case EVENT_SQUOTE: 351 case EVENT_DQUOTE: 352 arg->type = FILTER_ARG_VALUE; 353 arg->value.type = 354 type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR; 355 arg->value.str = strdup(token); 356 if (!arg->value.str) { 357 free_arg(arg); 358 show_error(error_str, "failed to allocate string filter arg"); 359 return TEP_ERRNO__MEM_ALLOC_FAILED; 360 } 361 break; 362 case EVENT_ITEM: 363 /* if it is a number, then convert it */ 364 if (isdigit(token[0])) { 365 arg->type = FILTER_ARG_VALUE; 366 arg->value.type = FILTER_NUMBER; 367 arg->value.val = strtoull(token, NULL, 0); 368 break; 369 } 370 /* Consider this a field */ 371 field = tep_find_any_field(event, token); 372 if (!field) { 373 /* If token is 'COMM' or 'CPU' then it is special */ 374 if (strcmp(token, COMM) == 0) { 375 field = &comm; 376 } else if (strcmp(token, CPU) == 0) { 377 field = &cpu; 378 } else { 379 /* not a field, Make it false */ 380 arg->type = FILTER_ARG_BOOLEAN; 381 arg->boolean.value = FILTER_FALSE; 382 break; 383 } 384 } 385 arg->type = FILTER_ARG_FIELD; 386 arg->field.field = field; 387 break; 388 default: 389 free_arg(arg); 390 show_error(error_str, "expected a value but found %s", token); 391 return TEP_ERRNO__UNEXPECTED_TYPE; 392 } 393 *parg = arg; 394 return 0; 395} 396 397static struct filter_arg * 398create_arg_op(enum filter_op_type btype) 399{ 400 struct filter_arg *arg; 401 402 arg = allocate_arg(); 403 if (!arg) 404 return NULL; 405 406 arg->type = FILTER_ARG_OP; 407 arg->op.type = btype; 408 409 return arg; 410} 411 412static struct filter_arg * 413create_arg_exp(enum filter_exp_type etype) 414{ 415 struct filter_arg *arg; 416 417 arg = allocate_arg(); 418 if (!arg) 419 return NULL; 420 421 arg->type = FILTER_ARG_EXP; 422 arg->exp.type = etype; 423 424 return arg; 425} 426 427static struct filter_arg * 428create_arg_cmp(enum filter_cmp_type ctype) 429{ 430 struct filter_arg *arg; 431 432 arg = allocate_arg(); 433 if (!arg) 434 return NULL; 435 436 /* Use NUM and change if necessary */ 437 arg->type = FILTER_ARG_NUM; 438 arg->num.type = ctype; 439 440 return arg; 441} 442 443static enum tep_errno 444add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str) 445{ 446 struct filter_arg *left; 447 char *str; 448 int op_type; 449 int ret; 450 451 switch (op->type) { 452 case FILTER_ARG_EXP: 453 if (op->exp.right) 454 goto out_fail; 455 op->exp.right = arg; 456 break; 457 458 case FILTER_ARG_OP: 459 if (op->op.right) 460 goto out_fail; 461 op->op.right = arg; 462 break; 463 464 case FILTER_ARG_NUM: 465 if (op->op.right) 466 goto out_fail; 467 /* 468 * The arg must be num, str, or field 469 */ 470 switch (arg->type) { 471 case FILTER_ARG_VALUE: 472 case FILTER_ARG_FIELD: 473 break; 474 default: 475 show_error(error_str, "Illegal rvalue"); 476 return TEP_ERRNO__ILLEGAL_RVALUE; 477 } 478 479 /* 480 * Depending on the type, we may need to 481 * convert this to a string or regex. 482 */ 483 switch (arg->value.type) { 484 case FILTER_CHAR: 485 /* 486 * A char should be converted to number if 487 * the string is 1 byte, and the compare 488 * is not a REGEX. 489 */ 490 if (strlen(arg->value.str) == 1 && 491 op->num.type != FILTER_CMP_REGEX && 492 op->num.type != FILTER_CMP_NOT_REGEX) { 493 arg->value.type = FILTER_NUMBER; 494 goto do_int; 495 } 496 /* fall through */ 497 case FILTER_STRING: 498 499 /* convert op to a string arg */ 500 op_type = op->num.type; 501 left = op->num.left; 502 str = arg->value.str; 503 504 /* reset the op for the new field */ 505 memset(op, 0, sizeof(*op)); 506 507 /* 508 * If left arg was a field not found then 509 * NULL the entire op. 510 */ 511 if (left->type == FILTER_ARG_BOOLEAN) { 512 free_arg(left); 513 free_arg(arg); 514 op->type = FILTER_ARG_BOOLEAN; 515 op->boolean.value = FILTER_FALSE; 516 break; 517 } 518 519 /* Left arg must be a field */ 520 if (left->type != FILTER_ARG_FIELD) { 521 show_error(error_str, 522 "Illegal lvalue for string comparison"); 523 return TEP_ERRNO__ILLEGAL_LVALUE; 524 } 525 526 /* Make sure this is a valid string compare */ 527 switch (op_type) { 528 case FILTER_CMP_EQ: 529 op_type = FILTER_CMP_MATCH; 530 break; 531 case FILTER_CMP_NE: 532 op_type = FILTER_CMP_NOT_MATCH; 533 break; 534 535 case FILTER_CMP_REGEX: 536 case FILTER_CMP_NOT_REGEX: 537 ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB); 538 if (ret) { 539 show_error(error_str, 540 "RegEx '%s' did not compute", 541 str); 542 return TEP_ERRNO__INVALID_REGEX; 543 } 544 break; 545 default: 546 show_error(error_str, 547 "Illegal comparison for string"); 548 return TEP_ERRNO__ILLEGAL_STRING_CMP; 549 } 550 551 op->type = FILTER_ARG_STR; 552 op->str.type = op_type; 553 op->str.field = left->field.field; 554 op->str.val = strdup(str); 555 if (!op->str.val) { 556 show_error(error_str, "Failed to allocate string filter"); 557 return TEP_ERRNO__MEM_ALLOC_FAILED; 558 } 559 /* 560 * Need a buffer to copy data for tests 561 */ 562 op->str.buffer = malloc(op->str.field->size + 1); 563 if (!op->str.buffer) { 564 show_error(error_str, "Failed to allocate string filter"); 565 return TEP_ERRNO__MEM_ALLOC_FAILED; 566 } 567 /* Null terminate this buffer */ 568 op->str.buffer[op->str.field->size] = 0; 569 570 /* We no longer have left or right args */ 571 free_arg(arg); 572 free_arg(left); 573 574 break; 575 576 case FILTER_NUMBER: 577 578 do_int: 579 switch (op->num.type) { 580 case FILTER_CMP_REGEX: 581 case FILTER_CMP_NOT_REGEX: 582 show_error(error_str, 583 "Op not allowed with integers"); 584 return TEP_ERRNO__ILLEGAL_INTEGER_CMP; 585 586 default: 587 break; 588 } 589 590 /* numeric compare */ 591 op->num.right = arg; 592 break; 593 default: 594 goto out_fail; 595 } 596 break; 597 default: 598 goto out_fail; 599 } 600 601 return 0; 602 603 out_fail: 604 show_error(error_str, "Syntax error"); 605 return TEP_ERRNO__SYNTAX_ERROR; 606} 607 608static struct filter_arg * 609rotate_op_right(struct filter_arg *a, struct filter_arg *b) 610{ 611 struct filter_arg *arg; 612 613 arg = a->op.right; 614 a->op.right = b; 615 return arg; 616} 617 618static enum tep_errno add_left(struct filter_arg *op, struct filter_arg *arg) 619{ 620 switch (op->type) { 621 case FILTER_ARG_EXP: 622 if (arg->type == FILTER_ARG_OP) 623 arg = rotate_op_right(arg, op); 624 op->exp.left = arg; 625 break; 626 627 case FILTER_ARG_OP: 628 op->op.left = arg; 629 break; 630 case FILTER_ARG_NUM: 631 if (arg->type == FILTER_ARG_OP) 632 arg = rotate_op_right(arg, op); 633 634 /* left arg of compares must be a field */ 635 if (arg->type != FILTER_ARG_FIELD && 636 arg->type != FILTER_ARG_BOOLEAN) 637 return TEP_ERRNO__INVALID_ARG_TYPE; 638 op->num.left = arg; 639 break; 640 default: 641 return TEP_ERRNO__INVALID_ARG_TYPE; 642 } 643 return 0; 644} 645 646enum op_type { 647 OP_NONE, 648 OP_BOOL, 649 OP_NOT, 650 OP_EXP, 651 OP_CMP, 652}; 653 654static enum op_type process_op(const char *token, 655 enum filter_op_type *btype, 656 enum filter_cmp_type *ctype, 657 enum filter_exp_type *etype) 658{ 659 *btype = FILTER_OP_NOT; 660 *etype = FILTER_EXP_NONE; 661 *ctype = FILTER_CMP_NONE; 662 663 if (strcmp(token, "&&") == 0) 664 *btype = FILTER_OP_AND; 665 else if (strcmp(token, "||") == 0) 666 *btype = FILTER_OP_OR; 667 else if (strcmp(token, "!") == 0) 668 return OP_NOT; 669 670 if (*btype != FILTER_OP_NOT) 671 return OP_BOOL; 672 673 /* Check for value expressions */ 674 if (strcmp(token, "+") == 0) { 675 *etype = FILTER_EXP_ADD; 676 } else if (strcmp(token, "-") == 0) { 677 *etype = FILTER_EXP_SUB; 678 } else if (strcmp(token, "*") == 0) { 679 *etype = FILTER_EXP_MUL; 680 } else if (strcmp(token, "/") == 0) { 681 *etype = FILTER_EXP_DIV; 682 } else if (strcmp(token, "%") == 0) { 683 *etype = FILTER_EXP_MOD; 684 } else if (strcmp(token, ">>") == 0) { 685 *etype = FILTER_EXP_RSHIFT; 686 } else if (strcmp(token, "<<") == 0) { 687 *etype = FILTER_EXP_LSHIFT; 688 } else if (strcmp(token, "&") == 0) { 689 *etype = FILTER_EXP_AND; 690 } else if (strcmp(token, "|") == 0) { 691 *etype = FILTER_EXP_OR; 692 } else if (strcmp(token, "^") == 0) { 693 *etype = FILTER_EXP_XOR; 694 } else if (strcmp(token, "~") == 0) 695 *etype = FILTER_EXP_NOT; 696 697 if (*etype != FILTER_EXP_NONE) 698 return OP_EXP; 699 700 /* Check for compares */ 701 if (strcmp(token, "==") == 0) 702 *ctype = FILTER_CMP_EQ; 703 else if (strcmp(token, "!=") == 0) 704 *ctype = FILTER_CMP_NE; 705 else if (strcmp(token, "<") == 0) 706 *ctype = FILTER_CMP_LT; 707 else if (strcmp(token, ">") == 0) 708 *ctype = FILTER_CMP_GT; 709 else if (strcmp(token, "<=") == 0) 710 *ctype = FILTER_CMP_LE; 711 else if (strcmp(token, ">=") == 0) 712 *ctype = FILTER_CMP_GE; 713 else if (strcmp(token, "=~") == 0) 714 *ctype = FILTER_CMP_REGEX; 715 else if (strcmp(token, "!~") == 0) 716 *ctype = FILTER_CMP_NOT_REGEX; 717 else 718 return OP_NONE; 719 720 return OP_CMP; 721} 722 723static int check_op_done(struct filter_arg *arg) 724{ 725 switch (arg->type) { 726 case FILTER_ARG_EXP: 727 return arg->exp.right != NULL; 728 729 case FILTER_ARG_OP: 730 return arg->op.right != NULL; 731 732 case FILTER_ARG_NUM: 733 return arg->num.right != NULL; 734 735 case FILTER_ARG_STR: 736 /* A string conversion is always done */ 737 return 1; 738 739 case FILTER_ARG_BOOLEAN: 740 /* field not found, is ok */ 741 return 1; 742 743 default: 744 return 0; 745 } 746} 747 748enum filter_vals { 749 FILTER_VAL_NORM, 750 FILTER_VAL_FALSE, 751 FILTER_VAL_TRUE, 752}; 753 754static enum tep_errno 755reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, 756 struct filter_arg *arg, char *error_str) 757{ 758 struct filter_arg *other_child; 759 struct filter_arg **ptr; 760 761 if (parent->type != FILTER_ARG_OP && 762 arg->type != FILTER_ARG_OP) { 763 show_error(error_str, "can not reparent other than OP"); 764 return TEP_ERRNO__REPARENT_NOT_OP; 765 } 766 767 /* Get the sibling */ 768 if (old_child->op.right == arg) { 769 ptr = &old_child->op.right; 770 other_child = old_child->op.left; 771 } else if (old_child->op.left == arg) { 772 ptr = &old_child->op.left; 773 other_child = old_child->op.right; 774 } else { 775 show_error(error_str, "Error in reparent op, find other child"); 776 return TEP_ERRNO__REPARENT_FAILED; 777 } 778 779 /* Detach arg from old_child */ 780 *ptr = NULL; 781 782 /* Check for root */ 783 if (parent == old_child) { 784 free_arg(other_child); 785 *parent = *arg; 786 /* Free arg without recussion */ 787 free(arg); 788 return 0; 789 } 790 791 if (parent->op.right == old_child) 792 ptr = &parent->op.right; 793 else if (parent->op.left == old_child) 794 ptr = &parent->op.left; 795 else { 796 show_error(error_str, "Error in reparent op"); 797 return TEP_ERRNO__REPARENT_FAILED; 798 } 799 800 *ptr = arg; 801 802 free_arg(old_child); 803 return 0; 804} 805 806/* Returns either filter_vals (success) or tep_errno (failfure) */ 807static int test_arg(struct filter_arg *parent, struct filter_arg *arg, 808 char *error_str) 809{ 810 int lval, rval; 811 812 switch (arg->type) { 813 814 /* bad case */ 815 case FILTER_ARG_BOOLEAN: 816 return FILTER_VAL_FALSE + arg->boolean.value; 817 818 /* good cases: */ 819 case FILTER_ARG_STR: 820 case FILTER_ARG_VALUE: 821 case FILTER_ARG_FIELD: 822 return FILTER_VAL_NORM; 823 824 case FILTER_ARG_EXP: 825 lval = test_arg(arg, arg->exp.left, error_str); 826 if (lval != FILTER_VAL_NORM) 827 return lval; 828 rval = test_arg(arg, arg->exp.right, error_str); 829 if (rval != FILTER_VAL_NORM) 830 return rval; 831 return FILTER_VAL_NORM; 832 833 case FILTER_ARG_NUM: 834 lval = test_arg(arg, arg->num.left, error_str); 835 if (lval != FILTER_VAL_NORM) 836 return lval; 837 rval = test_arg(arg, arg->num.right, error_str); 838 if (rval != FILTER_VAL_NORM) 839 return rval; 840 return FILTER_VAL_NORM; 841 842 case FILTER_ARG_OP: 843 if (arg->op.type != FILTER_OP_NOT) { 844 lval = test_arg(arg, arg->op.left, error_str); 845 switch (lval) { 846 case FILTER_VAL_NORM: 847 break; 848 case FILTER_VAL_TRUE: 849 if (arg->op.type == FILTER_OP_OR) 850 return FILTER_VAL_TRUE; 851 rval = test_arg(arg, arg->op.right, error_str); 852 if (rval != FILTER_VAL_NORM) 853 return rval; 854 855 return reparent_op_arg(parent, arg, arg->op.right, 856 error_str); 857 858 case FILTER_VAL_FALSE: 859 if (arg->op.type == FILTER_OP_AND) 860 return FILTER_VAL_FALSE; 861 rval = test_arg(arg, arg->op.right, error_str); 862 if (rval != FILTER_VAL_NORM) 863 return rval; 864 865 return reparent_op_arg(parent, arg, arg->op.right, 866 error_str); 867 868 default: 869 return lval; 870 } 871 } 872 873 rval = test_arg(arg, arg->op.right, error_str); 874 switch (rval) { 875 case FILTER_VAL_NORM: 876 default: 877 break; 878 879 case FILTER_VAL_TRUE: 880 if (arg->op.type == FILTER_OP_OR) 881 return FILTER_VAL_TRUE; 882 if (arg->op.type == FILTER_OP_NOT) 883 return FILTER_VAL_FALSE; 884 885 return reparent_op_arg(parent, arg, arg->op.left, 886 error_str); 887 888 case FILTER_VAL_FALSE: 889 if (arg->op.type == FILTER_OP_AND) 890 return FILTER_VAL_FALSE; 891 if (arg->op.type == FILTER_OP_NOT) 892 return FILTER_VAL_TRUE; 893 894 return reparent_op_arg(parent, arg, arg->op.left, 895 error_str); 896 } 897 898 return rval; 899 default: 900 show_error(error_str, "bad arg in filter tree"); 901 return TEP_ERRNO__BAD_FILTER_ARG; 902 } 903 return FILTER_VAL_NORM; 904} 905 906/* Remove any unknown event fields */ 907static int collapse_tree(struct filter_arg *arg, 908 struct filter_arg **arg_collapsed, char *error_str) 909{ 910 int ret; 911 912 ret = test_arg(arg, arg, error_str); 913 switch (ret) { 914 case FILTER_VAL_NORM: 915 break; 916 917 case FILTER_VAL_TRUE: 918 case FILTER_VAL_FALSE: 919 free_arg(arg); 920 arg = allocate_arg(); 921 if (arg) { 922 arg->type = FILTER_ARG_BOOLEAN; 923 arg->boolean.value = ret == FILTER_VAL_TRUE; 924 } else { 925 show_error(error_str, "Failed to allocate filter arg"); 926 ret = TEP_ERRNO__MEM_ALLOC_FAILED; 927 } 928 break; 929 930 default: 931 /* test_arg() already set the error_str */ 932 free_arg(arg); 933 arg = NULL; 934 break; 935 } 936 937 *arg_collapsed = arg; 938 return ret; 939} 940 941static enum tep_errno 942process_filter(struct event_format *event, struct filter_arg **parg, 943 char *error_str, int not) 944{ 945 enum event_type type; 946 char *token = NULL; 947 struct filter_arg *current_op = NULL; 948 struct filter_arg *current_exp = NULL; 949 struct filter_arg *left_item = NULL; 950 struct filter_arg *arg = NULL; 951 enum op_type op_type; 952 enum filter_op_type btype; 953 enum filter_exp_type etype; 954 enum filter_cmp_type ctype; 955 enum tep_errno ret; 956 957 *parg = NULL; 958 959 do { 960 free(token); 961 type = read_token(&token); 962 switch (type) { 963 case EVENT_SQUOTE: 964 case EVENT_DQUOTE: 965 case EVENT_ITEM: 966 ret = create_arg_item(event, token, type, &arg, error_str); 967 if (ret < 0) 968 goto fail; 969 if (!left_item) 970 left_item = arg; 971 else if (current_exp) { 972 ret = add_right(current_exp, arg, error_str); 973 if (ret < 0) 974 goto fail; 975 left_item = NULL; 976 /* Not's only one one expression */ 977 if (not) { 978 arg = NULL; 979 if (current_op) 980 goto fail_syntax; 981 free(token); 982 *parg = current_exp; 983 return 0; 984 } 985 } else 986 goto fail_syntax; 987 arg = NULL; 988 break; 989 990 case EVENT_DELIM: 991 if (*token == ',') { 992 show_error(error_str, "Illegal token ','"); 993 ret = TEP_ERRNO__ILLEGAL_TOKEN; 994 goto fail; 995 } 996 997 if (*token == '(') { 998 if (left_item) { 999 show_error(error_str, 1000 "Open paren can not come after item"); 1001 ret = TEP_ERRNO__INVALID_PAREN; 1002 goto fail; 1003 } 1004 if (current_exp) { 1005 show_error(error_str, 1006 "Open paren can not come after expression"); 1007 ret = TEP_ERRNO__INVALID_PAREN; 1008 goto fail; 1009 } 1010 1011 ret = process_filter(event, &arg, error_str, 0); 1012 if (ret != TEP_ERRNO__UNBALANCED_PAREN) { 1013 if (ret == 0) { 1014 show_error(error_str, 1015 "Unbalanced number of '('"); 1016 ret = TEP_ERRNO__UNBALANCED_PAREN; 1017 } 1018 goto fail; 1019 } 1020 ret = 0; 1021 1022 /* A not wants just one expression */ 1023 if (not) { 1024 if (current_op) 1025 goto fail_syntax; 1026 *parg = arg; 1027 return 0; 1028 } 1029 1030 if (current_op) 1031 ret = add_right(current_op, arg, error_str); 1032 else 1033 current_exp = arg; 1034 1035 if (ret < 0) 1036 goto fail; 1037 1038 } else { /* ')' */ 1039 if (!current_op && !current_exp) 1040 goto fail_syntax; 1041 1042 /* Make sure everything is finished at this level */ 1043 if (current_exp && !check_op_done(current_exp)) 1044 goto fail_syntax; 1045 if (current_op && !check_op_done(current_op)) 1046 goto fail_syntax; 1047 1048 if (current_op) 1049 *parg = current_op; 1050 else 1051 *parg = current_exp; 1052 free(token); 1053 return TEP_ERRNO__UNBALANCED_PAREN; 1054 } 1055 break; 1056 1057 case EVENT_OP: 1058 op_type = process_op(token, &btype, &ctype, &etype); 1059 1060 /* All expect a left arg except for NOT */ 1061 switch (op_type) { 1062 case OP_BOOL: 1063 /* Logic ops need a left expression */ 1064 if (!current_exp && !current_op) 1065 goto fail_syntax; 1066 /* fall through */ 1067 case OP_NOT: 1068 /* logic only processes ops and exp */ 1069 if (left_item) 1070 goto fail_syntax; 1071 break; 1072 case OP_EXP: 1073 case OP_CMP: 1074 if (!left_item) 1075 goto fail_syntax; 1076 break; 1077 case OP_NONE: 1078 show_error(error_str, 1079 "Unknown op token %s", token); 1080 ret = TEP_ERRNO__UNKNOWN_TOKEN; 1081 goto fail; 1082 } 1083 1084 ret = 0; 1085 switch (op_type) { 1086 case OP_BOOL: 1087 arg = create_arg_op(btype); 1088 if (arg == NULL) 1089 goto fail_alloc; 1090 if (current_op) 1091 ret = add_left(arg, current_op); 1092 else 1093 ret = add_left(arg, current_exp); 1094 current_op = arg; 1095 current_exp = NULL; 1096 break; 1097 1098 case OP_NOT: 1099 arg = create_arg_op(btype); 1100 if (arg == NULL) 1101 goto fail_alloc; 1102 if (current_op) 1103 ret = add_right(current_op, arg, error_str); 1104 if (ret < 0) 1105 goto fail; 1106 current_exp = arg; 1107 ret = process_filter(event, &arg, error_str, 1); 1108 if (ret < 0) 1109 goto fail; 1110 ret = add_right(current_exp, arg, error_str); 1111 if (ret < 0) 1112 goto fail; 1113 break; 1114 1115 case OP_EXP: 1116 case OP_CMP: 1117 if (op_type == OP_EXP) 1118 arg = create_arg_exp(etype); 1119 else 1120 arg = create_arg_cmp(ctype); 1121 if (arg == NULL) 1122 goto fail_alloc; 1123 1124 if (current_op) 1125 ret = add_right(current_op, arg, error_str); 1126 if (ret < 0) 1127 goto fail; 1128 ret = add_left(arg, left_item); 1129 if (ret < 0) { 1130 arg = NULL; 1131 goto fail_syntax; 1132 } 1133 current_exp = arg; 1134 break; 1135 default: 1136 break; 1137 } 1138 arg = NULL; 1139 if (ret < 0) 1140 goto fail_syntax; 1141 break; 1142 case EVENT_NONE: 1143 break; 1144 case EVENT_ERROR: 1145 goto fail_alloc; 1146 default: 1147 goto fail_syntax; 1148 } 1149 } while (type != EVENT_NONE); 1150 1151 if (!current_op && !current_exp) 1152 goto fail_syntax; 1153 1154 if (!current_op) 1155 current_op = current_exp; 1156 1157 ret = collapse_tree(current_op, parg, error_str); 1158 /* collapse_tree() may free current_op, and updates parg accordingly */ 1159 current_op = NULL; 1160 if (ret < 0) 1161 goto fail; 1162 1163 free(token); 1164 return 0; 1165 1166 fail_alloc: 1167 show_error(error_str, "failed to allocate filter arg"); 1168 ret = TEP_ERRNO__MEM_ALLOC_FAILED; 1169 goto fail; 1170 fail_syntax: 1171 show_error(error_str, "Syntax error"); 1172 ret = TEP_ERRNO__SYNTAX_ERROR; 1173 fail: 1174 free_arg(current_op); 1175 free_arg(current_exp); 1176 free_arg(arg); 1177 free(token); 1178 return ret; 1179} 1180 1181static enum tep_errno 1182process_event(struct event_format *event, const char *filter_str, 1183 struct filter_arg **parg, char *error_str) 1184{ 1185 int ret; 1186 1187 tep_buffer_init(filter_str, strlen(filter_str)); 1188 1189 ret = process_filter(event, parg, error_str, 0); 1190 if (ret < 0) 1191 return ret; 1192 1193 /* If parg is NULL, then make it into FALSE */ 1194 if (!*parg) { 1195 *parg = allocate_arg(); 1196 if (*parg == NULL) 1197 return TEP_ERRNO__MEM_ALLOC_FAILED; 1198 1199 (*parg)->type = FILTER_ARG_BOOLEAN; 1200 (*parg)->boolean.value = FILTER_FALSE; 1201 } 1202 1203 return 0; 1204} 1205 1206static enum tep_errno 1207filter_event(struct event_filter *filter, struct event_format *event, 1208 const char *filter_str, char *error_str) 1209{ 1210 struct filter_type *filter_type; 1211 struct filter_arg *arg; 1212 enum tep_errno ret; 1213 1214 if (filter_str) { 1215 ret = process_event(event, filter_str, &arg, error_str); 1216 if (ret < 0) 1217 return ret; 1218 1219 } else { 1220 /* just add a TRUE arg */ 1221 arg = allocate_arg(); 1222 if (arg == NULL) 1223 return TEP_ERRNO__MEM_ALLOC_FAILED; 1224 1225 arg->type = FILTER_ARG_BOOLEAN; 1226 arg->boolean.value = FILTER_TRUE; 1227 } 1228 1229 filter_type = add_filter_type(filter, event->id); 1230 if (filter_type == NULL) 1231 return TEP_ERRNO__MEM_ALLOC_FAILED; 1232 1233 if (filter_type->filter) 1234 free_arg(filter_type->filter); 1235 filter_type->filter = arg; 1236 1237 return 0; 1238} 1239 1240static void filter_init_error_buf(struct event_filter *filter) 1241{ 1242 /* clear buffer to reset show error */ 1243 tep_buffer_init("", 0); 1244 filter->error_buffer[0] = '\0'; 1245} 1246 1247/** 1248 * tep_filter_add_filter_str - add a new filter 1249 * @filter: the event filter to add to 1250 * @filter_str: the filter string that contains the filter 1251 * 1252 * Returns 0 if the filter was successfully added or a 1253 * negative error code. Use tep_filter_strerror() to see 1254 * actual error message in case of error. 1255 */ 1256enum tep_errno tep_filter_add_filter_str(struct event_filter *filter, 1257 const char *filter_str) 1258{ 1259 struct tep_handle *pevent = filter->pevent; 1260 struct event_list *event; 1261 struct event_list *events = NULL; 1262 const char *filter_start; 1263 const char *next_event; 1264 char *this_event; 1265 char *event_name = NULL; 1266 char *sys_name = NULL; 1267 char *sp; 1268 enum tep_errno rtn = 0; /* TEP_ERRNO__SUCCESS */ 1269 int len; 1270 int ret; 1271 1272 filter_init_error_buf(filter); 1273 1274 filter_start = strchr(filter_str, ':'); 1275 if (filter_start) 1276 len = filter_start - filter_str; 1277 else 1278 len = strlen(filter_str); 1279 1280 do { 1281 next_event = strchr(filter_str, ','); 1282 if (next_event && 1283 (!filter_start || next_event < filter_start)) 1284 len = next_event - filter_str; 1285 else if (filter_start) 1286 len = filter_start - filter_str; 1287 else 1288 len = strlen(filter_str); 1289 1290 this_event = malloc(len + 1); 1291 if (this_event == NULL) { 1292 /* This can only happen when events is NULL, but still */ 1293 free_events(events); 1294 return TEP_ERRNO__MEM_ALLOC_FAILED; 1295 } 1296 memcpy(this_event, filter_str, len); 1297 this_event[len] = 0; 1298 1299 if (next_event) 1300 next_event++; 1301 1302 filter_str = next_event; 1303 1304 sys_name = strtok_r(this_event, "/", &sp); 1305 event_name = strtok_r(NULL, "/", &sp); 1306 1307 if (!sys_name) { 1308 /* This can only happen when events is NULL, but still */ 1309 free_events(events); 1310 free(this_event); 1311 return TEP_ERRNO__FILTER_NOT_FOUND; 1312 } 1313 1314 /* Find this event */ 1315 ret = find_event(pevent, &events, strim(sys_name), strim(event_name)); 1316 if (ret < 0) { 1317 free_events(events); 1318 free(this_event); 1319 return ret; 1320 } 1321 free(this_event); 1322 } while (filter_str); 1323 1324 /* Skip the ':' */ 1325 if (filter_start) 1326 filter_start++; 1327 1328 /* filter starts here */ 1329 for (event = events; event; event = event->next) { 1330 ret = filter_event(filter, event->event, filter_start, 1331 filter->error_buffer); 1332 /* Failures are returned if a parse error happened */ 1333 if (ret < 0) 1334 rtn = ret; 1335 1336 if (ret >= 0 && pevent->test_filters) { 1337 char *test; 1338 test = tep_filter_make_string(filter, event->event->id); 1339 if (test) { 1340 printf(" '%s: %s'\n", event->event->name, test); 1341 free(test); 1342 } 1343 } 1344 } 1345 1346 free_events(events); 1347 1348 if (rtn >= 0 && pevent->test_filters) 1349 exit(0); 1350 1351 return rtn; 1352} 1353 1354static void free_filter_type(struct filter_type *filter_type) 1355{ 1356 free_arg(filter_type->filter); 1357} 1358 1359/** 1360 * tep_filter_strerror - fill error message in a buffer 1361 * @filter: the event filter contains error 1362 * @err: the error code 1363 * @buf: the buffer to be filled in 1364 * @buflen: the size of the buffer 1365 * 1366 * Returns 0 if message was filled successfully, -1 if error 1367 */ 1368int tep_filter_strerror(struct event_filter *filter, enum tep_errno err, 1369 char *buf, size_t buflen) 1370{ 1371 if (err <= __TEP_ERRNO__START || err >= __TEP_ERRNO__END) 1372 return -1; 1373 1374 if (strlen(filter->error_buffer) > 0) { 1375 size_t len = snprintf(buf, buflen, "%s", filter->error_buffer); 1376 1377 if (len > buflen) 1378 return -1; 1379 return 0; 1380 } 1381 1382 return tep_strerror(filter->pevent, err, buf, buflen); 1383} 1384 1385/** 1386 * tep_filter_remove_event - remove a filter for an event 1387 * @filter: the event filter to remove from 1388 * @event_id: the event to remove a filter for 1389 * 1390 * Removes the filter saved for an event defined by @event_id 1391 * from the @filter. 1392 * 1393 * Returns 1: if an event was removed 1394 * 0: if the event was not found 1395 */ 1396int tep_filter_remove_event(struct event_filter *filter, 1397 int event_id) 1398{ 1399 struct filter_type *filter_type; 1400 unsigned long len; 1401 1402 if (!filter->filters) 1403 return 0; 1404 1405 filter_type = find_filter_type(filter, event_id); 1406 1407 if (!filter_type) 1408 return 0; 1409 1410 free_filter_type(filter_type); 1411 1412 /* The filter_type points into the event_filters array */ 1413 len = (unsigned long)(filter->event_filters + filter->filters) - 1414 (unsigned long)(filter_type + 1); 1415 1416 memmove(filter_type, filter_type + 1, len); 1417 filter->filters--; 1418 1419 memset(&filter->event_filters[filter->filters], 0, 1420 sizeof(*filter_type)); 1421 1422 return 1; 1423} 1424 1425/** 1426 * tep_filter_reset - clear all filters in a filter 1427 * @filter: the event filter to reset 1428 * 1429 * Removes all filters from a filter and resets it. 1430 */ 1431void tep_filter_reset(struct event_filter *filter) 1432{ 1433 int i; 1434 1435 for (i = 0; i < filter->filters; i++) 1436 free_filter_type(&filter->event_filters[i]); 1437 1438 free(filter->event_filters); 1439 filter->filters = 0; 1440 filter->event_filters = NULL; 1441} 1442 1443void tep_filter_free(struct event_filter *filter) 1444{ 1445 tep_unref(filter->pevent); 1446 1447 tep_filter_reset(filter); 1448 1449 free(filter); 1450} 1451 1452static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg); 1453 1454static int copy_filter_type(struct event_filter *filter, 1455 struct event_filter *source, 1456 struct filter_type *filter_type) 1457{ 1458 struct filter_arg *arg; 1459 struct event_format *event; 1460 const char *sys; 1461 const char *name; 1462 char *str; 1463 1464 /* Can't assume that the pevent's are the same */ 1465 sys = filter_type->event->system; 1466 name = filter_type->event->name; 1467 event = tep_find_event_by_name(filter->pevent, sys, name); 1468 if (!event) 1469 return -1; 1470 1471 str = arg_to_str(source, filter_type->filter); 1472 if (!str) 1473 return -1; 1474 1475 if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) { 1476 /* Add trivial event */ 1477 arg = allocate_arg(); 1478 if (arg == NULL) 1479 return -1; 1480 1481 arg->type = FILTER_ARG_BOOLEAN; 1482 if (strcmp(str, "TRUE") == 0) 1483 arg->boolean.value = 1; 1484 else 1485 arg->boolean.value = 0; 1486 1487 filter_type = add_filter_type(filter, event->id); 1488 if (filter_type == NULL) 1489 return -1; 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 event_filter *dest, struct 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 1525/** 1526 * tep_update_trivial - update the trivial filters with the given filter 1527 * @dest - the filter to update 1528 * @source - the filter as the source of the update 1529 * @type - the type of trivial filter to update. 1530 * 1531 * Scan dest for trivial events matching @type to replace with the source. 1532 * 1533 * Returns 0 on success and -1 if there was a problem updating, but 1534 * events may have still been updated on error. 1535 */ 1536int tep_update_trivial(struct event_filter *dest, struct event_filter *source, 1537 enum filter_trivial_type type) 1538{ 1539 struct tep_handle *src_pevent; 1540 struct tep_handle *dest_pevent; 1541 struct event_format *event; 1542 struct filter_type *filter_type; 1543 struct filter_arg *arg; 1544 char *str; 1545 int i; 1546 1547 src_pevent = source->pevent; 1548 dest_pevent = dest->pevent; 1549 1550 /* Do nothing if either of the filters has nothing to filter */ 1551 if (!dest->filters || !source->filters) 1552 return 0; 1553 1554 for (i = 0; i < dest->filters; i++) { 1555 filter_type = &dest->event_filters[i]; 1556 arg = filter_type->filter; 1557 if (arg->type != FILTER_ARG_BOOLEAN) 1558 continue; 1559 if ((arg->boolean.value && type == FILTER_TRIVIAL_FALSE) || 1560 (!arg->boolean.value && type == FILTER_TRIVIAL_TRUE)) 1561 continue; 1562 1563 event = filter_type->event; 1564 1565 if (src_pevent != dest_pevent) { 1566 /* do a look up */ 1567 event = tep_find_event_by_name(src_pevent, 1568 event->system, 1569 event->name); 1570 if (!event) 1571 return -1; 1572 } 1573 1574 str = tep_filter_make_string(source, event->id); 1575 if (!str) 1576 continue; 1577 1578 /* Don't bother if the filter is trivial too */ 1579 if (strcmp(str, "TRUE") != 0 && strcmp(str, "FALSE") != 0) 1580 filter_event(dest, event, str, NULL); 1581 free(str); 1582 } 1583 return 0; 1584} 1585 1586/** 1587 * tep_filter_clear_trivial - clear TRUE and FALSE filters 1588 * @filter: the filter to remove trivial filters from 1589 * @type: remove only true, false, or both 1590 * 1591 * Removes filters that only contain a TRUE or FALES boolean arg. 1592 * 1593 * Returns 0 on success and -1 if there was a problem. 1594 */ 1595int tep_filter_clear_trivial(struct event_filter *filter, 1596 enum filter_trivial_type type) 1597{ 1598 struct filter_type *filter_type; 1599 int count = 0; 1600 int *ids = NULL; 1601 int i; 1602 1603 if (!filter->filters) 1604 return 0; 1605 1606 /* 1607 * Two steps, first get all ids with trivial filters. 1608 * then remove those ids. 1609 */ 1610 for (i = 0; i < filter->filters; i++) { 1611 int *new_ids; 1612 1613 filter_type = &filter->event_filters[i]; 1614 if (filter_type->filter->type != FILTER_ARG_BOOLEAN) 1615 continue; 1616 switch (type) { 1617 case FILTER_TRIVIAL_FALSE: 1618 if (filter_type->filter->boolean.value) 1619 continue; 1620 break; 1621 case FILTER_TRIVIAL_TRUE: 1622 if (!filter_type->filter->boolean.value) 1623 continue; 1624 default: 1625 break; 1626 } 1627 1628 new_ids = realloc(ids, sizeof(*ids) * (count + 1)); 1629 if (!new_ids) { 1630 free(ids); 1631 return -1; 1632 } 1633 1634 ids = new_ids; 1635 ids[count++] = filter_type->event_id; 1636 } 1637 1638 if (!count) 1639 return 0; 1640 1641 for (i = 0; i < count; i++) 1642 tep_filter_remove_event(filter, ids[i]); 1643 1644 free(ids); 1645 return 0; 1646} 1647 1648/** 1649 * tep_filter_event_has_trivial - return true event contains trivial filter 1650 * @filter: the filter with the information 1651 * @event_id: the id of the event to test 1652 * @type: trivial type to test for (TRUE, FALSE, EITHER) 1653 * 1654 * Returns 1 if the event contains a matching trivial type 1655 * otherwise 0. 1656 */ 1657int tep_filter_event_has_trivial(struct event_filter *filter, 1658 int event_id, 1659 enum filter_trivial_type type) 1660{ 1661 struct filter_type *filter_type; 1662 1663 if (!filter->filters) 1664 return 0; 1665 1666 filter_type = find_filter_type(filter, event_id); 1667 1668 if (!filter_type) 1669 return 0; 1670 1671 if (filter_type->filter->type != FILTER_ARG_BOOLEAN) 1672 return 0; 1673 1674 switch (type) { 1675 case FILTER_TRIVIAL_FALSE: 1676 return !filter_type->filter->boolean.value; 1677 1678 case FILTER_TRIVIAL_TRUE: 1679 return filter_type->filter->boolean.value; 1680 default: 1681 return 1; 1682 } 1683} 1684 1685static int test_filter(struct event_format *event, struct filter_arg *arg, 1686 struct tep_record *record, enum tep_errno *err); 1687 1688static const char * 1689get_comm(struct event_format *event, struct tep_record *record) 1690{ 1691 const char *comm; 1692 int pid; 1693 1694 pid = tep_data_pid(event->pevent, record); 1695 comm = tep_data_comm_from_pid(event->pevent, pid); 1696 return comm; 1697} 1698 1699static unsigned long long 1700get_value(struct event_format *event, 1701 struct format_field *field, struct tep_record *record) 1702{ 1703 unsigned long long val; 1704 1705 /* Handle our dummy "comm" field */ 1706 if (field == &comm) { 1707 const char *name; 1708 1709 name = get_comm(event, record); 1710 return (unsigned long)name; 1711 } 1712 1713 /* Handle our dummy "cpu" field */ 1714 if (field == &cpu) 1715 return record->cpu; 1716 1717 tep_read_number_field(field, record->data, &val); 1718 1719 if (!(field->flags & FIELD_IS_SIGNED)) 1720 return val; 1721 1722 switch (field->size) { 1723 case 1: 1724 return (char)val; 1725 case 2: 1726 return (short)val; 1727 case 4: 1728 return (int)val; 1729 case 8: 1730 return (long long)val; 1731 } 1732 return val; 1733} 1734 1735static unsigned long long 1736get_arg_value(struct event_format *event, struct filter_arg *arg, 1737 struct tep_record *record, enum tep_errno *err); 1738 1739static unsigned long long 1740get_exp_value(struct event_format *event, struct filter_arg *arg, 1741 struct tep_record *record, enum tep_errno *err) 1742{ 1743 unsigned long long lval, rval; 1744 1745 lval = get_arg_value(event, arg->exp.left, record, err); 1746 rval = get_arg_value(event, arg->exp.right, record, err); 1747 1748 if (*err) { 1749 /* 1750 * There was an error, no need to process anymore. 1751 */ 1752 return 0; 1753 } 1754 1755 switch (arg->exp.type) { 1756 case FILTER_EXP_ADD: 1757 return lval + rval; 1758 1759 case FILTER_EXP_SUB: 1760 return lval - rval; 1761 1762 case FILTER_EXP_MUL: 1763 return lval * rval; 1764 1765 case FILTER_EXP_DIV: 1766 return lval / rval; 1767 1768 case FILTER_EXP_MOD: 1769 return lval % rval; 1770 1771 case FILTER_EXP_RSHIFT: 1772 return lval >> rval; 1773 1774 case FILTER_EXP_LSHIFT: 1775 return lval << rval; 1776 1777 case FILTER_EXP_AND: 1778 return lval & rval; 1779 1780 case FILTER_EXP_OR: 1781 return lval | rval; 1782 1783 case FILTER_EXP_XOR: 1784 return lval ^ rval; 1785 1786 case FILTER_EXP_NOT: 1787 default: 1788 if (!*err) 1789 *err = TEP_ERRNO__INVALID_EXP_TYPE; 1790 } 1791 return 0; 1792} 1793 1794static unsigned long long 1795get_arg_value(struct event_format *event, struct filter_arg *arg, 1796 struct tep_record *record, enum tep_errno *err) 1797{ 1798 switch (arg->type) { 1799 case FILTER_ARG_FIELD: 1800 return get_value(event, arg->field.field, record); 1801 1802 case FILTER_ARG_VALUE: 1803 if (arg->value.type != FILTER_NUMBER) { 1804 if (!*err) 1805 *err = TEP_ERRNO__NOT_A_NUMBER; 1806 } 1807 return arg->value.val; 1808 1809 case FILTER_ARG_EXP: 1810 return get_exp_value(event, arg, record, err); 1811 1812 default: 1813 if (!*err) 1814 *err = TEP_ERRNO__INVALID_ARG_TYPE; 1815 } 1816 return 0; 1817} 1818 1819static int test_num(struct event_format *event, struct filter_arg *arg, 1820 struct tep_record *record, enum tep_errno *err) 1821{ 1822 unsigned long long lval, rval; 1823 1824 lval = get_arg_value(event, arg->num.left, record, err); 1825 rval = get_arg_value(event, arg->num.right, record, err); 1826 1827 if (*err) { 1828 /* 1829 * There was an error, no need to process anymore. 1830 */ 1831 return 0; 1832 } 1833 1834 switch (arg->num.type) { 1835 case FILTER_CMP_EQ: 1836 return lval == rval; 1837 1838 case FILTER_CMP_NE: 1839 return lval != rval; 1840 1841 case FILTER_CMP_GT: 1842 return lval > rval; 1843 1844 case FILTER_CMP_LT: 1845 return lval < rval; 1846 1847 case FILTER_CMP_GE: 1848 return lval >= rval; 1849 1850 case FILTER_CMP_LE: 1851 return lval <= rval; 1852 1853 default: 1854 if (!*err) 1855 *err = TEP_ERRNO__ILLEGAL_INTEGER_CMP; 1856 return 0; 1857 } 1858} 1859 1860static const char *get_field_str(struct filter_arg *arg, struct tep_record *record) 1861{ 1862 struct event_format *event; 1863 struct tep_handle *pevent; 1864 unsigned long long addr; 1865 const char *val = NULL; 1866 unsigned int size; 1867 char hex[64]; 1868 1869 /* If the field is not a string convert it */ 1870 if (arg->str.field->flags & FIELD_IS_STRING) { 1871 val = record->data + arg->str.field->offset; 1872 size = arg->str.field->size; 1873 1874 if (arg->str.field->flags & FIELD_IS_DYNAMIC) { 1875 addr = *(unsigned int *)val; 1876 val = record->data + (addr & 0xffff); 1877 size = addr >> 16; 1878 } 1879 1880 /* 1881 * We need to copy the data since we can't be sure the field 1882 * is null terminated. 1883 */ 1884 if (*(val + size - 1)) { 1885 /* copy it */ 1886 memcpy(arg->str.buffer, val, arg->str.field->size); 1887 /* the buffer is already NULL terminated */ 1888 val = arg->str.buffer; 1889 } 1890 1891 } else { 1892 event = arg->str.field->event; 1893 pevent = event->pevent; 1894 addr = get_value(event, arg->str.field, record); 1895 1896 if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG)) 1897 /* convert to a kernel symbol */ 1898 val = tep_find_function(pevent, addr); 1899 1900 if (val == NULL) { 1901 /* just use the hex of the string name */ 1902 snprintf(hex, 64, "0x%llx", addr); 1903 val = hex; 1904 } 1905 } 1906 1907 return val; 1908} 1909 1910static int test_str(struct event_format *event, struct filter_arg *arg, 1911 struct tep_record *record, enum tep_errno *err) 1912{ 1913 const char *val; 1914 1915 if (arg->str.field == &comm) 1916 val = get_comm(event, record); 1917 else 1918 val = get_field_str(arg, record); 1919 1920 switch (arg->str.type) { 1921 case FILTER_CMP_MATCH: 1922 return strcmp(val, arg->str.val) == 0; 1923 1924 case FILTER_CMP_NOT_MATCH: 1925 return strcmp(val, arg->str.val) != 0; 1926 1927 case FILTER_CMP_REGEX: 1928 /* Returns zero on match */ 1929 return !regexec(&arg->str.reg, val, 0, NULL, 0); 1930 1931 case FILTER_CMP_NOT_REGEX: 1932 return regexec(&arg->str.reg, val, 0, NULL, 0); 1933 1934 default: 1935 if (!*err) 1936 *err = TEP_ERRNO__ILLEGAL_STRING_CMP; 1937 return 0; 1938 } 1939} 1940 1941static int test_op(struct event_format *event, struct filter_arg *arg, 1942 struct tep_record *record, enum tep_errno *err) 1943{ 1944 switch (arg->op.type) { 1945 case FILTER_OP_AND: 1946 return test_filter(event, arg->op.left, record, err) && 1947 test_filter(event, arg->op.right, record, err); 1948 1949 case FILTER_OP_OR: 1950 return test_filter(event, arg->op.left, record, err) || 1951 test_filter(event, arg->op.right, record, err); 1952 1953 case FILTER_OP_NOT: 1954 return !test_filter(event, arg->op.right, record, err); 1955 1956 default: 1957 if (!*err) 1958 *err = TEP_ERRNO__INVALID_OP_TYPE; 1959 return 0; 1960 } 1961} 1962 1963static int test_filter(struct event_format *event, struct filter_arg *arg, 1964 struct tep_record *record, enum tep_errno *err) 1965{ 1966 if (*err) { 1967 /* 1968 * There was an error, no need to process anymore. 1969 */ 1970 return 0; 1971 } 1972 1973 switch (arg->type) { 1974 case FILTER_ARG_BOOLEAN: 1975 /* easy case */ 1976 return arg->boolean.value; 1977 1978 case FILTER_ARG_OP: 1979 return test_op(event, arg, record, err); 1980 1981 case FILTER_ARG_NUM: 1982 return test_num(event, arg, record, err); 1983 1984 case FILTER_ARG_STR: 1985 return test_str(event, arg, record, err); 1986 1987 case FILTER_ARG_EXP: 1988 case FILTER_ARG_VALUE: 1989 case FILTER_ARG_FIELD: 1990 /* 1991 * Expressions, fields and values evaluate 1992 * to true if they return non zero 1993 */ 1994 return !!get_arg_value(event, arg, record, err); 1995 1996 default: 1997 if (!*err) 1998 *err = TEP_ERRNO__INVALID_ARG_TYPE; 1999 return 0; 2000 } 2001} 2002 2003/** 2004 * tep_event_filtered - return true if event has filter 2005 * @filter: filter struct with filter information 2006 * @event_id: event id to test if filter exists 2007 * 2008 * Returns 1 if filter found for @event_id 2009 * otherwise 0; 2010 */ 2011int tep_event_filtered(struct event_filter *filter, int event_id) 2012{ 2013 struct filter_type *filter_type; 2014 2015 if (!filter->filters) 2016 return 0; 2017 2018 filter_type = find_filter_type(filter, event_id); 2019 2020 return filter_type ? 1 : 0; 2021} 2022 2023/** 2024 * tep_filter_match - test if a record matches a filter 2025 * @filter: filter struct with filter information 2026 * @record: the record to test against the filter 2027 * 2028 * Returns: match result or error code (prefixed with TEP_ERRNO__) 2029 * FILTER_MATCH - filter found for event and @record matches 2030 * FILTER_MISS - filter found for event and @record does not match 2031 * FILTER_NOT_FOUND - no filter found for @record's event 2032 * NO_FILTER - if no filters exist 2033 * otherwise - error occurred during test 2034 */ 2035enum tep_errno tep_filter_match(struct event_filter *filter, 2036 struct tep_record *record) 2037{ 2038 struct tep_handle *pevent = filter->pevent; 2039 struct filter_type *filter_type; 2040 int event_id; 2041 int ret; 2042 enum tep_errno err = 0; 2043 2044 filter_init_error_buf(filter); 2045 2046 if (!filter->filters) 2047 return TEP_ERRNO__NO_FILTER; 2048 2049 event_id = tep_data_type(pevent, record); 2050 2051 filter_type = find_filter_type(filter, event_id); 2052 if (!filter_type) 2053 return TEP_ERRNO__FILTER_NOT_FOUND; 2054 2055 ret = test_filter(filter_type->event, filter_type->filter, record, &err); 2056 if (err) 2057 return err; 2058 2059 return ret ? TEP_ERRNO__FILTER_MATCH : TEP_ERRNO__FILTER_MISS; 2060} 2061 2062static char *op_to_str(struct event_filter *filter, struct filter_arg *arg) 2063{ 2064 char *str = NULL; 2065 char *left = NULL; 2066 char *right = NULL; 2067 char *op = NULL; 2068 int left_val = -1; 2069 int right_val = -1; 2070 int val; 2071 2072 switch (arg->op.type) { 2073 case FILTER_OP_AND: 2074 op = "&&"; 2075 /* fall through */ 2076 case FILTER_OP_OR: 2077 if (!op) 2078 op = "||"; 2079 2080 left = arg_to_str(filter, arg->op.left); 2081 right = arg_to_str(filter, arg->op.right); 2082 if (!left || !right) 2083 break; 2084 2085 /* Try to consolidate boolean values */ 2086 if (strcmp(left, "TRUE") == 0) 2087 left_val = 1; 2088 else if (strcmp(left, "FALSE") == 0) 2089 left_val = 0; 2090 2091 if (strcmp(right, "TRUE") == 0) 2092 right_val = 1; 2093 else if (strcmp(right, "FALSE") == 0) 2094 right_val = 0; 2095 2096 if (left_val >= 0) { 2097 if ((arg->op.type == FILTER_OP_AND && !left_val) || 2098 (arg->op.type == FILTER_OP_OR && left_val)) { 2099 /* Just return left value */ 2100 str = left; 2101 left = NULL; 2102 break; 2103 } 2104 if (right_val >= 0) { 2105 /* just evaluate this. */ 2106 val = 0; 2107 switch (arg->op.type) { 2108 case FILTER_OP_AND: 2109 val = left_val && right_val; 2110 break; 2111 case FILTER_OP_OR: 2112 val = left_val || right_val; 2113 break; 2114 default: 2115 break; 2116 } 2117 asprintf(&str, val ? "TRUE" : "FALSE"); 2118 break; 2119 } 2120 } 2121 if (right_val >= 0) { 2122 if ((arg->op.type == FILTER_OP_AND && !right_val) || 2123 (arg->op.type == FILTER_OP_OR && right_val)) { 2124 /* Just return right value */ 2125 str = right; 2126 right = NULL; 2127 break; 2128 } 2129 /* The right value is meaningless */ 2130 str = left; 2131 left = NULL; 2132 break; 2133 } 2134 2135 asprintf(&str, "(%s) %s (%s)", left, op, right); 2136 break; 2137 2138 case FILTER_OP_NOT: 2139 op = "!"; 2140 right = arg_to_str(filter, arg->op.right); 2141 if (!right) 2142 break; 2143 2144 /* See if we can consolidate */ 2145 if (strcmp(right, "TRUE") == 0) 2146 right_val = 1; 2147 else if (strcmp(right, "FALSE") == 0) 2148 right_val = 0; 2149 if (right_val >= 0) { 2150 /* just return the opposite */ 2151 asprintf(&str, right_val ? "FALSE" : "TRUE"); 2152 break; 2153 } 2154 asprintf(&str, "%s(%s)", op, right); 2155 break; 2156 2157 default: 2158 /* ?? */ 2159 break; 2160 } 2161 free(left); 2162 free(right); 2163 return str; 2164} 2165 2166static char *val_to_str(struct event_filter *filter, struct filter_arg *arg) 2167{ 2168 char *str = NULL; 2169 2170 asprintf(&str, "%lld", arg->value.val); 2171 2172 return str; 2173} 2174 2175static char *field_to_str(struct event_filter *filter, struct filter_arg *arg) 2176{ 2177 return strdup(arg->field.field->name); 2178} 2179 2180static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg) 2181{ 2182 char *lstr; 2183 char *rstr; 2184 char *op; 2185 char *str = NULL; 2186 2187 lstr = arg_to_str(filter, arg->exp.left); 2188 rstr = arg_to_str(filter, arg->exp.right); 2189 if (!lstr || !rstr) 2190 goto out; 2191 2192 switch (arg->exp.type) { 2193 case FILTER_EXP_ADD: 2194 op = "+"; 2195 break; 2196 case FILTER_EXP_SUB: 2197 op = "-"; 2198 break; 2199 case FILTER_EXP_MUL: 2200 op = "*"; 2201 break; 2202 case FILTER_EXP_DIV: 2203 op = "/"; 2204 break; 2205 case FILTER_EXP_MOD: 2206 op = "%"; 2207 break; 2208 case FILTER_EXP_RSHIFT: 2209 op = ">>"; 2210 break; 2211 case FILTER_EXP_LSHIFT: 2212 op = "<<"; 2213 break; 2214 case FILTER_EXP_AND: 2215 op = "&"; 2216 break; 2217 case FILTER_EXP_OR: 2218 op = "|"; 2219 break; 2220 case FILTER_EXP_XOR: 2221 op = "^"; 2222 break; 2223 default: 2224 op = "[ERROR IN EXPRESSION TYPE]"; 2225 break; 2226 } 2227 2228 asprintf(&str, "%s %s %s", lstr, op, rstr); 2229out: 2230 free(lstr); 2231 free(rstr); 2232 2233 return str; 2234} 2235 2236static char *num_to_str(struct event_filter *filter, struct filter_arg *arg) 2237{ 2238 char *lstr; 2239 char *rstr; 2240 char *str = NULL; 2241 char *op = NULL; 2242 2243 lstr = arg_to_str(filter, arg->num.left); 2244 rstr = arg_to_str(filter, arg->num.right); 2245 if (!lstr || !rstr) 2246 goto out; 2247 2248 switch (arg->num.type) { 2249 case FILTER_CMP_EQ: 2250 op = "=="; 2251 /* fall through */ 2252 case FILTER_CMP_NE: 2253 if (!op) 2254 op = "!="; 2255 /* fall through */ 2256 case FILTER_CMP_GT: 2257 if (!op) 2258 op = ">"; 2259 /* fall through */ 2260 case FILTER_CMP_LT: 2261 if (!op) 2262 op = "<"; 2263 /* fall through */ 2264 case FILTER_CMP_GE: 2265 if (!op) 2266 op = ">="; 2267 /* fall through */ 2268 case FILTER_CMP_LE: 2269 if (!op) 2270 op = "<="; 2271 2272 asprintf(&str, "%s %s %s", lstr, op, rstr); 2273 break; 2274 2275 default: 2276 /* ?? */ 2277 break; 2278 } 2279 2280out: 2281 free(lstr); 2282 free(rstr); 2283 return str; 2284} 2285 2286static char *str_to_str(struct event_filter *filter, struct filter_arg *arg) 2287{ 2288 char *str = NULL; 2289 char *op = NULL; 2290 2291 switch (arg->str.type) { 2292 case FILTER_CMP_MATCH: 2293 op = "=="; 2294 /* fall through */ 2295 case FILTER_CMP_NOT_MATCH: 2296 if (!op) 2297 op = "!="; 2298 /* fall through */ 2299 case FILTER_CMP_REGEX: 2300 if (!op) 2301 op = "=~"; 2302 /* fall through */ 2303 case FILTER_CMP_NOT_REGEX: 2304 if (!op) 2305 op = "!~"; 2306 2307 asprintf(&str, "%s %s \"%s\"", 2308 arg->str.field->name, op, arg->str.val); 2309 break; 2310 2311 default: 2312 /* ?? */ 2313 break; 2314 } 2315 return str; 2316} 2317 2318static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg) 2319{ 2320 char *str = NULL; 2321 2322 switch (arg->type) { 2323 case FILTER_ARG_BOOLEAN: 2324 asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE"); 2325 return str; 2326 2327 case FILTER_ARG_OP: 2328 return op_to_str(filter, arg); 2329 2330 case FILTER_ARG_NUM: 2331 return num_to_str(filter, arg); 2332 2333 case FILTER_ARG_STR: 2334 return str_to_str(filter, arg); 2335 2336 case FILTER_ARG_VALUE: 2337 return val_to_str(filter, arg); 2338 2339 case FILTER_ARG_FIELD: 2340 return field_to_str(filter, arg); 2341 2342 case FILTER_ARG_EXP: 2343 return exp_to_str(filter, arg); 2344 2345 default: 2346 /* ?? */ 2347 return NULL; 2348 } 2349 2350} 2351 2352/** 2353 * tep_filter_make_string - return a string showing the filter 2354 * @filter: filter struct with filter information 2355 * @event_id: the event id to return the filter string with 2356 * 2357 * Returns a string that displays the filter contents. 2358 * This string must be freed with free(str). 2359 * NULL is returned if no filter is found or allocation failed. 2360 */ 2361char * 2362tep_filter_make_string(struct event_filter *filter, int event_id) 2363{ 2364 struct filter_type *filter_type; 2365 2366 if (!filter->filters) 2367 return NULL; 2368 2369 filter_type = find_filter_type(filter, event_id); 2370 2371 if (!filter_type) 2372 return NULL; 2373 2374 return arg_to_str(filter, filter_type->filter); 2375} 2376 2377/** 2378 * tep_filter_compare - compare two filters and return if they are the same 2379 * @filter1: Filter to compare with @filter2 2380 * @filter2: Filter to compare with @filter1 2381 * 2382 * Returns: 2383 * 1 if the two filters hold the same content. 2384 * 0 if they do not. 2385 */ 2386int tep_filter_compare(struct event_filter *filter1, struct event_filter *filter2) 2387{ 2388 struct filter_type *filter_type1; 2389 struct filter_type *filter_type2; 2390 char *str1, *str2; 2391 int result; 2392 int i; 2393 2394 /* Do the easy checks first */ 2395 if (filter1->filters != filter2->filters) 2396 return 0; 2397 if (!filter1->filters && !filter2->filters) 2398 return 1; 2399 2400 /* 2401 * Now take a look at each of the events to see if they have the same 2402 * filters to them. 2403 */ 2404 for (i = 0; i < filter1->filters; i++) { 2405 filter_type1 = &filter1->event_filters[i]; 2406 filter_type2 = find_filter_type(filter2, filter_type1->event_id); 2407 if (!filter_type2) 2408 break; 2409 if (filter_type1->filter->type != filter_type2->filter->type) 2410 break; 2411 switch (filter_type1->filter->type) { 2412 case FILTER_TRIVIAL_FALSE: 2413 case FILTER_TRIVIAL_TRUE: 2414 /* trivial types just need the type compared */ 2415 continue; 2416 default: 2417 break; 2418 } 2419 /* The best way to compare complex filters is with strings */ 2420 str1 = arg_to_str(filter1, filter_type1->filter); 2421 str2 = arg_to_str(filter2, filter_type2->filter); 2422 if (str1 && str2) 2423 result = strcmp(str1, str2) != 0; 2424 else 2425 /* bail out if allocation fails */ 2426 result = 1; 2427 2428 free(str1); 2429 free(str2); 2430 if (result) 2431 break; 2432 } 2433 2434 if (i < filter1->filters) 2435 return 0; 2436 return 1; 2437} 2438