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