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