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