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