at v5.7 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 free_arg(arg); 1233 return TEP_ERRNO__MEM_ALLOC_FAILED; 1234 } 1235 1236 if (filter_type->filter) 1237 free_arg(filter_type->filter); 1238 filter_type->filter = arg; 1239 1240 return 0; 1241} 1242 1243static void filter_init_error_buf(struct tep_event_filter *filter) 1244{ 1245 /* clear buffer to reset show error */ 1246 tep_buffer_init("", 0); 1247 filter->error_buffer[0] = '\0'; 1248} 1249 1250/** 1251 * tep_filter_add_filter_str - add a new filter 1252 * @filter: the event filter to add to 1253 * @filter_str: the filter string that contains the filter 1254 * 1255 * Returns 0 if the filter was successfully added or a 1256 * negative error code. Use tep_filter_strerror() to see 1257 * actual error message in case of error. 1258 */ 1259enum tep_errno tep_filter_add_filter_str(struct tep_event_filter *filter, 1260 const char *filter_str) 1261{ 1262 struct tep_handle *tep = filter->tep; 1263 struct event_list *event; 1264 struct event_list *events = NULL; 1265 const char *filter_start; 1266 const char *next_event; 1267 char *this_event; 1268 char *event_name = NULL; 1269 char *sys_name = NULL; 1270 char *sp; 1271 enum tep_errno rtn = 0; /* TEP_ERRNO__SUCCESS */ 1272 int len; 1273 int ret; 1274 1275 filter_init_error_buf(filter); 1276 1277 filter_start = strchr(filter_str, ':'); 1278 if (filter_start) 1279 len = filter_start - filter_str; 1280 else 1281 len = strlen(filter_str); 1282 1283 do { 1284 next_event = strchr(filter_str, ','); 1285 if (next_event && 1286 (!filter_start || next_event < filter_start)) 1287 len = next_event - filter_str; 1288 else if (filter_start) 1289 len = filter_start - filter_str; 1290 else 1291 len = strlen(filter_str); 1292 1293 this_event = malloc(len + 1); 1294 if (this_event == NULL) { 1295 /* This can only happen when events is NULL, but still */ 1296 free_events(events); 1297 return TEP_ERRNO__MEM_ALLOC_FAILED; 1298 } 1299 memcpy(this_event, filter_str, len); 1300 this_event[len] = 0; 1301 1302 if (next_event) 1303 next_event++; 1304 1305 filter_str = next_event; 1306 1307 sys_name = strtok_r(this_event, "/", &sp); 1308 event_name = strtok_r(NULL, "/", &sp); 1309 1310 if (!sys_name) { 1311 /* This can only happen when events is NULL, but still */ 1312 free_events(events); 1313 free(this_event); 1314 return TEP_ERRNO__FILTER_NOT_FOUND; 1315 } 1316 1317 /* Find this event */ 1318 ret = find_event(tep, &events, strim(sys_name), strim(event_name)); 1319 if (ret < 0) { 1320 free_events(events); 1321 free(this_event); 1322 return ret; 1323 } 1324 free(this_event); 1325 } while (filter_str); 1326 1327 /* Skip the ':' */ 1328 if (filter_start) 1329 filter_start++; 1330 1331 /* filter starts here */ 1332 for (event = events; event; event = event->next) { 1333 ret = filter_event(filter, event->event, filter_start, 1334 filter->error_buffer); 1335 /* Failures are returned if a parse error happened */ 1336 if (ret < 0) 1337 rtn = ret; 1338 1339 if (ret >= 0 && tep->test_filters) { 1340 char *test; 1341 test = tep_filter_make_string(filter, event->event->id); 1342 if (test) { 1343 printf(" '%s: %s'\n", event->event->name, test); 1344 free(test); 1345 } 1346 } 1347 } 1348 1349 free_events(events); 1350 1351 return rtn; 1352} 1353 1354static void free_filter_type(struct tep_filter_type *filter_type) 1355{ 1356 free_arg(filter_type->filter); 1357} 1358 1359/** 1360 * tep_filter_strerror - fill error message in a buffer 1361 * @filter: the event filter contains error 1362 * @err: the error code 1363 * @buf: the buffer to be filled in 1364 * @buflen: the size of the buffer 1365 * 1366 * Returns 0 if message was filled successfully, -1 if error 1367 */ 1368int tep_filter_strerror(struct tep_event_filter *filter, enum tep_errno err, 1369 char *buf, size_t buflen) 1370{ 1371 if (err <= __TEP_ERRNO__START || err >= __TEP_ERRNO__END) 1372 return -1; 1373 1374 if (strlen(filter->error_buffer) > 0) { 1375 size_t len = snprintf(buf, buflen, "%s", filter->error_buffer); 1376 1377 if (len > buflen) 1378 return -1; 1379 return 0; 1380 } 1381 1382 return tep_strerror(filter->tep, err, buf, buflen); 1383} 1384 1385/** 1386 * tep_filter_remove_event - remove a filter for an event 1387 * @filter: the event filter to remove from 1388 * @event_id: the event to remove a filter for 1389 * 1390 * Removes the filter saved for an event defined by @event_id 1391 * from the @filter. 1392 * 1393 * Returns 1: if an event was removed 1394 * 0: if the event was not found 1395 */ 1396int tep_filter_remove_event(struct tep_event_filter *filter, 1397 int event_id) 1398{ 1399 struct tep_filter_type *filter_type; 1400 unsigned long len; 1401 1402 if (!filter->filters) 1403 return 0; 1404 1405 filter_type = find_filter_type(filter, event_id); 1406 1407 if (!filter_type) 1408 return 0; 1409 1410 free_filter_type(filter_type); 1411 1412 /* The filter_type points into the event_filters array */ 1413 len = (unsigned long)(filter->event_filters + filter->filters) - 1414 (unsigned long)(filter_type + 1); 1415 1416 memmove(filter_type, filter_type + 1, len); 1417 filter->filters--; 1418 1419 memset(&filter->event_filters[filter->filters], 0, 1420 sizeof(*filter_type)); 1421 1422 return 1; 1423} 1424 1425/** 1426 * tep_filter_reset - clear all filters in a filter 1427 * @filter: the event filter to reset 1428 * 1429 * Removes all filters from a filter and resets it. 1430 */ 1431void tep_filter_reset(struct tep_event_filter *filter) 1432{ 1433 int i; 1434 1435 for (i = 0; i < filter->filters; i++) 1436 free_filter_type(&filter->event_filters[i]); 1437 1438 free(filter->event_filters); 1439 filter->filters = 0; 1440 filter->event_filters = NULL; 1441} 1442 1443void tep_filter_free(struct tep_event_filter *filter) 1444{ 1445 tep_unref(filter->tep); 1446 1447 tep_filter_reset(filter); 1448 1449 free(filter); 1450} 1451 1452static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg); 1453 1454static int copy_filter_type(struct tep_event_filter *filter, 1455 struct tep_event_filter *source, 1456 struct tep_filter_type *filter_type) 1457{ 1458 struct tep_filter_arg *arg; 1459 struct tep_event *event; 1460 const char *sys; 1461 const char *name; 1462 char *str; 1463 1464 /* Can't assume that the tep's are the same */ 1465 sys = filter_type->event->system; 1466 name = filter_type->event->name; 1467 event = tep_find_event_by_name(filter->tep, sys, name); 1468 if (!event) 1469 return -1; 1470 1471 str = arg_to_str(source, filter_type->filter); 1472 if (!str) 1473 return -1; 1474 1475 if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) { 1476 /* Add trivial event */ 1477 arg = allocate_arg(); 1478 if (arg == NULL) { 1479 free(str); 1480 return -1; 1481 } 1482 1483 arg->type = TEP_FILTER_ARG_BOOLEAN; 1484 if (strcmp(str, "TRUE") == 0) 1485 arg->boolean.value = 1; 1486 else 1487 arg->boolean.value = 0; 1488 1489 filter_type = add_filter_type(filter, event->id); 1490 if (filter_type == NULL) { 1491 free(str); 1492 free_arg(arg); 1493 return -1; 1494 } 1495 1496 filter_type->filter = arg; 1497 1498 free(str); 1499 return 0; 1500 } 1501 1502 filter_event(filter, event, str, NULL); 1503 free(str); 1504 1505 return 0; 1506} 1507 1508/** 1509 * tep_filter_copy - copy a filter using another filter 1510 * @dest - the filter to copy to 1511 * @source - the filter to copy from 1512 * 1513 * Returns 0 on success and -1 if not all filters were copied 1514 */ 1515int tep_filter_copy(struct tep_event_filter *dest, struct tep_event_filter *source) 1516{ 1517 int ret = 0; 1518 int i; 1519 1520 tep_filter_reset(dest); 1521 1522 for (i = 0; i < source->filters; i++) { 1523 if (copy_filter_type(dest, source, &source->event_filters[i])) 1524 ret = -1; 1525 } 1526 return ret; 1527} 1528 1529static int test_filter(struct tep_event *event, struct tep_filter_arg *arg, 1530 struct tep_record *record, enum tep_errno *err); 1531 1532static const char * 1533get_comm(struct tep_event *event, struct tep_record *record) 1534{ 1535 const char *comm; 1536 int pid; 1537 1538 pid = tep_data_pid(event->tep, record); 1539 comm = tep_data_comm_from_pid(event->tep, pid); 1540 return comm; 1541} 1542 1543static unsigned long long 1544get_value(struct tep_event *event, 1545 struct tep_format_field *field, struct tep_record *record) 1546{ 1547 unsigned long long val; 1548 1549 /* Handle our dummy "comm" field */ 1550 if (field == &comm) { 1551 const char *name; 1552 1553 name = get_comm(event, record); 1554 return (unsigned long)name; 1555 } 1556 1557 /* Handle our dummy "cpu" field */ 1558 if (field == &cpu) 1559 return record->cpu; 1560 1561 tep_read_number_field(field, record->data, &val); 1562 1563 if (!(field->flags & TEP_FIELD_IS_SIGNED)) 1564 return val; 1565 1566 switch (field->size) { 1567 case 1: 1568 return (char)val; 1569 case 2: 1570 return (short)val; 1571 case 4: 1572 return (int)val; 1573 case 8: 1574 return (long long)val; 1575 } 1576 return val; 1577} 1578 1579static unsigned long long 1580get_arg_value(struct tep_event *event, struct tep_filter_arg *arg, 1581 struct tep_record *record, enum tep_errno *err); 1582 1583static unsigned long long 1584get_exp_value(struct tep_event *event, struct tep_filter_arg *arg, 1585 struct tep_record *record, enum tep_errno *err) 1586{ 1587 unsigned long long lval, rval; 1588 1589 lval = get_arg_value(event, arg->exp.left, record, err); 1590 rval = get_arg_value(event, arg->exp.right, record, err); 1591 1592 if (*err) { 1593 /* 1594 * There was an error, no need to process anymore. 1595 */ 1596 return 0; 1597 } 1598 1599 switch (arg->exp.type) { 1600 case TEP_FILTER_EXP_ADD: 1601 return lval + rval; 1602 1603 case TEP_FILTER_EXP_SUB: 1604 return lval - rval; 1605 1606 case TEP_FILTER_EXP_MUL: 1607 return lval * rval; 1608 1609 case TEP_FILTER_EXP_DIV: 1610 return lval / rval; 1611 1612 case TEP_FILTER_EXP_MOD: 1613 return lval % rval; 1614 1615 case TEP_FILTER_EXP_RSHIFT: 1616 return lval >> rval; 1617 1618 case TEP_FILTER_EXP_LSHIFT: 1619 return lval << rval; 1620 1621 case TEP_FILTER_EXP_AND: 1622 return lval & rval; 1623 1624 case TEP_FILTER_EXP_OR: 1625 return lval | rval; 1626 1627 case TEP_FILTER_EXP_XOR: 1628 return lval ^ rval; 1629 1630 case TEP_FILTER_EXP_NOT: 1631 default: 1632 if (!*err) 1633 *err = TEP_ERRNO__INVALID_EXP_TYPE; 1634 } 1635 return 0; 1636} 1637 1638static unsigned long long 1639get_arg_value(struct tep_event *event, struct tep_filter_arg *arg, 1640 struct tep_record *record, enum tep_errno *err) 1641{ 1642 switch (arg->type) { 1643 case TEP_FILTER_ARG_FIELD: 1644 return get_value(event, arg->field.field, record); 1645 1646 case TEP_FILTER_ARG_VALUE: 1647 if (arg->value.type != TEP_FILTER_NUMBER) { 1648 if (!*err) 1649 *err = TEP_ERRNO__NOT_A_NUMBER; 1650 } 1651 return arg->value.val; 1652 1653 case TEP_FILTER_ARG_EXP: 1654 return get_exp_value(event, arg, record, err); 1655 1656 default: 1657 if (!*err) 1658 *err = TEP_ERRNO__INVALID_ARG_TYPE; 1659 } 1660 return 0; 1661} 1662 1663static int test_num(struct tep_event *event, struct tep_filter_arg *arg, 1664 struct tep_record *record, enum tep_errno *err) 1665{ 1666 unsigned long long lval, rval; 1667 1668 lval = get_arg_value(event, arg->num.left, record, err); 1669 rval = get_arg_value(event, arg->num.right, record, err); 1670 1671 if (*err) { 1672 /* 1673 * There was an error, no need to process anymore. 1674 */ 1675 return 0; 1676 } 1677 1678 switch (arg->num.type) { 1679 case TEP_FILTER_CMP_EQ: 1680 return lval == rval; 1681 1682 case TEP_FILTER_CMP_NE: 1683 return lval != rval; 1684 1685 case TEP_FILTER_CMP_GT: 1686 return lval > rval; 1687 1688 case TEP_FILTER_CMP_LT: 1689 return lval < rval; 1690 1691 case TEP_FILTER_CMP_GE: 1692 return lval >= rval; 1693 1694 case TEP_FILTER_CMP_LE: 1695 return lval <= rval; 1696 1697 default: 1698 if (!*err) 1699 *err = TEP_ERRNO__ILLEGAL_INTEGER_CMP; 1700 return 0; 1701 } 1702} 1703 1704static const char *get_field_str(struct tep_filter_arg *arg, struct tep_record *record) 1705{ 1706 struct tep_event *event; 1707 struct tep_handle *tep; 1708 unsigned long long addr; 1709 const char *val = NULL; 1710 unsigned int size; 1711 char hex[64]; 1712 1713 /* If the field is not a string convert it */ 1714 if (arg->str.field->flags & TEP_FIELD_IS_STRING) { 1715 val = record->data + arg->str.field->offset; 1716 size = arg->str.field->size; 1717 1718 if (arg->str.field->flags & TEP_FIELD_IS_DYNAMIC) { 1719 addr = *(unsigned int *)val; 1720 val = record->data + (addr & 0xffff); 1721 size = addr >> 16; 1722 } 1723 1724 /* 1725 * We need to copy the data since we can't be sure the field 1726 * is null terminated. 1727 */ 1728 if (*(val + size - 1)) { 1729 /* copy it */ 1730 memcpy(arg->str.buffer, val, arg->str.field->size); 1731 /* the buffer is already NULL terminated */ 1732 val = arg->str.buffer; 1733 } 1734 1735 } else { 1736 event = arg->str.field->event; 1737 tep = event->tep; 1738 addr = get_value(event, arg->str.field, record); 1739 1740 if (arg->str.field->flags & (TEP_FIELD_IS_POINTER | TEP_FIELD_IS_LONG)) 1741 /* convert to a kernel symbol */ 1742 val = tep_find_function(tep, addr); 1743 1744 if (val == NULL) { 1745 /* just use the hex of the string name */ 1746 snprintf(hex, 64, "0x%llx", addr); 1747 val = hex; 1748 } 1749 } 1750 1751 return val; 1752} 1753 1754static int test_str(struct tep_event *event, struct tep_filter_arg *arg, 1755 struct tep_record *record, enum tep_errno *err) 1756{ 1757 const char *val; 1758 1759 if (arg->str.field == &comm) 1760 val = get_comm(event, record); 1761 else 1762 val = get_field_str(arg, record); 1763 1764 switch (arg->str.type) { 1765 case TEP_FILTER_CMP_MATCH: 1766 return strcmp(val, arg->str.val) == 0; 1767 1768 case TEP_FILTER_CMP_NOT_MATCH: 1769 return strcmp(val, arg->str.val) != 0; 1770 1771 case TEP_FILTER_CMP_REGEX: 1772 /* Returns zero on match */ 1773 return !regexec(&arg->str.reg, val, 0, NULL, 0); 1774 1775 case TEP_FILTER_CMP_NOT_REGEX: 1776 return regexec(&arg->str.reg, val, 0, NULL, 0); 1777 1778 default: 1779 if (!*err) 1780 *err = TEP_ERRNO__ILLEGAL_STRING_CMP; 1781 return 0; 1782 } 1783} 1784 1785static int test_op(struct tep_event *event, struct tep_filter_arg *arg, 1786 struct tep_record *record, enum tep_errno *err) 1787{ 1788 switch (arg->op.type) { 1789 case TEP_FILTER_OP_AND: 1790 return test_filter(event, arg->op.left, record, err) && 1791 test_filter(event, arg->op.right, record, err); 1792 1793 case TEP_FILTER_OP_OR: 1794 return test_filter(event, arg->op.left, record, err) || 1795 test_filter(event, arg->op.right, record, err); 1796 1797 case TEP_FILTER_OP_NOT: 1798 return !test_filter(event, arg->op.right, record, err); 1799 1800 default: 1801 if (!*err) 1802 *err = TEP_ERRNO__INVALID_OP_TYPE; 1803 return 0; 1804 } 1805} 1806 1807static int test_filter(struct tep_event *event, struct tep_filter_arg *arg, 1808 struct tep_record *record, enum tep_errno *err) 1809{ 1810 if (*err) { 1811 /* 1812 * There was an error, no need to process anymore. 1813 */ 1814 return 0; 1815 } 1816 1817 switch (arg->type) { 1818 case TEP_FILTER_ARG_BOOLEAN: 1819 /* easy case */ 1820 return arg->boolean.value; 1821 1822 case TEP_FILTER_ARG_OP: 1823 return test_op(event, arg, record, err); 1824 1825 case TEP_FILTER_ARG_NUM: 1826 return test_num(event, arg, record, err); 1827 1828 case TEP_FILTER_ARG_STR: 1829 return test_str(event, arg, record, err); 1830 1831 case TEP_FILTER_ARG_EXP: 1832 case TEP_FILTER_ARG_VALUE: 1833 case TEP_FILTER_ARG_FIELD: 1834 /* 1835 * Expressions, fields and values evaluate 1836 * to true if they return non zero 1837 */ 1838 return !!get_arg_value(event, arg, record, err); 1839 1840 default: 1841 if (!*err) 1842 *err = TEP_ERRNO__INVALID_ARG_TYPE; 1843 return 0; 1844 } 1845} 1846 1847/** 1848 * tep_event_filtered - return true if event has filter 1849 * @filter: filter struct with filter information 1850 * @event_id: event id to test if filter exists 1851 * 1852 * Returns 1 if filter found for @event_id 1853 * otherwise 0; 1854 */ 1855int tep_event_filtered(struct tep_event_filter *filter, int event_id) 1856{ 1857 struct tep_filter_type *filter_type; 1858 1859 if (!filter->filters) 1860 return 0; 1861 1862 filter_type = find_filter_type(filter, event_id); 1863 1864 return filter_type ? 1 : 0; 1865} 1866 1867/** 1868 * tep_filter_match - test if a record matches a filter 1869 * @filter: filter struct with filter information 1870 * @record: the record to test against the filter 1871 * 1872 * Returns: match result or error code (prefixed with TEP_ERRNO__) 1873 * FILTER_MATCH - filter found for event and @record matches 1874 * FILTER_MISS - filter found for event and @record does not match 1875 * FILTER_NOT_FOUND - no filter found for @record's event 1876 * NO_FILTER - if no filters exist 1877 * otherwise - error occurred during test 1878 */ 1879enum tep_errno tep_filter_match(struct tep_event_filter *filter, 1880 struct tep_record *record) 1881{ 1882 struct tep_handle *tep = filter->tep; 1883 struct tep_filter_type *filter_type; 1884 int event_id; 1885 int ret; 1886 enum tep_errno err = 0; 1887 1888 filter_init_error_buf(filter); 1889 1890 if (!filter->filters) 1891 return TEP_ERRNO__NO_FILTER; 1892 1893 event_id = tep_data_type(tep, record); 1894 1895 filter_type = find_filter_type(filter, event_id); 1896 if (!filter_type) 1897 return TEP_ERRNO__FILTER_NOT_FOUND; 1898 1899 ret = test_filter(filter_type->event, filter_type->filter, record, &err); 1900 if (err) 1901 return err; 1902 1903 return ret ? TEP_ERRNO__FILTER_MATCH : TEP_ERRNO__FILTER_MISS; 1904} 1905 1906static char *op_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 1907{ 1908 char *str = NULL; 1909 char *left = NULL; 1910 char *right = NULL; 1911 char *op = NULL; 1912 int left_val = -1; 1913 int right_val = -1; 1914 int val; 1915 1916 switch (arg->op.type) { 1917 case TEP_FILTER_OP_AND: 1918 op = "&&"; 1919 /* fall through */ 1920 case TEP_FILTER_OP_OR: 1921 if (!op) 1922 op = "||"; 1923 1924 left = arg_to_str(filter, arg->op.left); 1925 right = arg_to_str(filter, arg->op.right); 1926 if (!left || !right) 1927 break; 1928 1929 /* Try to consolidate boolean values */ 1930 if (strcmp(left, "TRUE") == 0) 1931 left_val = 1; 1932 else if (strcmp(left, "FALSE") == 0) 1933 left_val = 0; 1934 1935 if (strcmp(right, "TRUE") == 0) 1936 right_val = 1; 1937 else if (strcmp(right, "FALSE") == 0) 1938 right_val = 0; 1939 1940 if (left_val >= 0) { 1941 if ((arg->op.type == TEP_FILTER_OP_AND && !left_val) || 1942 (arg->op.type == TEP_FILTER_OP_OR && left_val)) { 1943 /* Just return left value */ 1944 str = left; 1945 left = NULL; 1946 break; 1947 } 1948 if (right_val >= 0) { 1949 /* just evaluate this. */ 1950 val = 0; 1951 switch (arg->op.type) { 1952 case TEP_FILTER_OP_AND: 1953 val = left_val && right_val; 1954 break; 1955 case TEP_FILTER_OP_OR: 1956 val = left_val || right_val; 1957 break; 1958 default: 1959 break; 1960 } 1961 asprintf(&str, val ? "TRUE" : "FALSE"); 1962 break; 1963 } 1964 } 1965 if (right_val >= 0) { 1966 if ((arg->op.type == TEP_FILTER_OP_AND && !right_val) || 1967 (arg->op.type == TEP_FILTER_OP_OR && right_val)) { 1968 /* Just return right value */ 1969 str = right; 1970 right = NULL; 1971 break; 1972 } 1973 /* The right value is meaningless */ 1974 str = left; 1975 left = NULL; 1976 break; 1977 } 1978 1979 asprintf(&str, "(%s) %s (%s)", left, op, right); 1980 break; 1981 1982 case TEP_FILTER_OP_NOT: 1983 op = "!"; 1984 right = arg_to_str(filter, arg->op.right); 1985 if (!right) 1986 break; 1987 1988 /* See if we can consolidate */ 1989 if (strcmp(right, "TRUE") == 0) 1990 right_val = 1; 1991 else if (strcmp(right, "FALSE") == 0) 1992 right_val = 0; 1993 if (right_val >= 0) { 1994 /* just return the opposite */ 1995 asprintf(&str, right_val ? "FALSE" : "TRUE"); 1996 break; 1997 } 1998 asprintf(&str, "%s(%s)", op, right); 1999 break; 2000 2001 default: 2002 /* ?? */ 2003 break; 2004 } 2005 free(left); 2006 free(right); 2007 return str; 2008} 2009 2010static char *val_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2011{ 2012 char *str = NULL; 2013 2014 asprintf(&str, "%lld", arg->value.val); 2015 2016 return str; 2017} 2018 2019static char *field_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2020{ 2021 return strdup(arg->field.field->name); 2022} 2023 2024static char *exp_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2025{ 2026 char *lstr; 2027 char *rstr; 2028 char *op; 2029 char *str = NULL; 2030 2031 lstr = arg_to_str(filter, arg->exp.left); 2032 rstr = arg_to_str(filter, arg->exp.right); 2033 if (!lstr || !rstr) 2034 goto out; 2035 2036 switch (arg->exp.type) { 2037 case TEP_FILTER_EXP_ADD: 2038 op = "+"; 2039 break; 2040 case TEP_FILTER_EXP_SUB: 2041 op = "-"; 2042 break; 2043 case TEP_FILTER_EXP_MUL: 2044 op = "*"; 2045 break; 2046 case TEP_FILTER_EXP_DIV: 2047 op = "/"; 2048 break; 2049 case TEP_FILTER_EXP_MOD: 2050 op = "%"; 2051 break; 2052 case TEP_FILTER_EXP_RSHIFT: 2053 op = ">>"; 2054 break; 2055 case TEP_FILTER_EXP_LSHIFT: 2056 op = "<<"; 2057 break; 2058 case TEP_FILTER_EXP_AND: 2059 op = "&"; 2060 break; 2061 case TEP_FILTER_EXP_OR: 2062 op = "|"; 2063 break; 2064 case TEP_FILTER_EXP_XOR: 2065 op = "^"; 2066 break; 2067 default: 2068 op = "[ERROR IN EXPRESSION TYPE]"; 2069 break; 2070 } 2071 2072 asprintf(&str, "%s %s %s", lstr, op, rstr); 2073out: 2074 free(lstr); 2075 free(rstr); 2076 2077 return str; 2078} 2079 2080static char *num_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2081{ 2082 char *lstr; 2083 char *rstr; 2084 char *str = NULL; 2085 char *op = NULL; 2086 2087 lstr = arg_to_str(filter, arg->num.left); 2088 rstr = arg_to_str(filter, arg->num.right); 2089 if (!lstr || !rstr) 2090 goto out; 2091 2092 switch (arg->num.type) { 2093 case TEP_FILTER_CMP_EQ: 2094 op = "=="; 2095 /* fall through */ 2096 case TEP_FILTER_CMP_NE: 2097 if (!op) 2098 op = "!="; 2099 /* fall through */ 2100 case TEP_FILTER_CMP_GT: 2101 if (!op) 2102 op = ">"; 2103 /* fall through */ 2104 case TEP_FILTER_CMP_LT: 2105 if (!op) 2106 op = "<"; 2107 /* fall through */ 2108 case TEP_FILTER_CMP_GE: 2109 if (!op) 2110 op = ">="; 2111 /* fall through */ 2112 case TEP_FILTER_CMP_LE: 2113 if (!op) 2114 op = "<="; 2115 2116 asprintf(&str, "%s %s %s", lstr, op, rstr); 2117 break; 2118 2119 default: 2120 /* ?? */ 2121 break; 2122 } 2123 2124out: 2125 free(lstr); 2126 free(rstr); 2127 return str; 2128} 2129 2130static char *str_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2131{ 2132 char *str = NULL; 2133 char *op = NULL; 2134 2135 switch (arg->str.type) { 2136 case TEP_FILTER_CMP_MATCH: 2137 op = "=="; 2138 /* fall through */ 2139 case TEP_FILTER_CMP_NOT_MATCH: 2140 if (!op) 2141 op = "!="; 2142 /* fall through */ 2143 case TEP_FILTER_CMP_REGEX: 2144 if (!op) 2145 op = "=~"; 2146 /* fall through */ 2147 case TEP_FILTER_CMP_NOT_REGEX: 2148 if (!op) 2149 op = "!~"; 2150 2151 asprintf(&str, "%s %s \"%s\"", 2152 arg->str.field->name, op, arg->str.val); 2153 break; 2154 2155 default: 2156 /* ?? */ 2157 break; 2158 } 2159 return str; 2160} 2161 2162static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2163{ 2164 char *str = NULL; 2165 2166 switch (arg->type) { 2167 case TEP_FILTER_ARG_BOOLEAN: 2168 asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE"); 2169 return str; 2170 2171 case TEP_FILTER_ARG_OP: 2172 return op_to_str(filter, arg); 2173 2174 case TEP_FILTER_ARG_NUM: 2175 return num_to_str(filter, arg); 2176 2177 case TEP_FILTER_ARG_STR: 2178 return str_to_str(filter, arg); 2179 2180 case TEP_FILTER_ARG_VALUE: 2181 return val_to_str(filter, arg); 2182 2183 case TEP_FILTER_ARG_FIELD: 2184 return field_to_str(filter, arg); 2185 2186 case TEP_FILTER_ARG_EXP: 2187 return exp_to_str(filter, arg); 2188 2189 default: 2190 /* ?? */ 2191 return NULL; 2192 } 2193 2194} 2195 2196/** 2197 * tep_filter_make_string - return a string showing the filter 2198 * @filter: filter struct with filter information 2199 * @event_id: the event id to return the filter string with 2200 * 2201 * Returns a string that displays the filter contents. 2202 * This string must be freed with free(str). 2203 * NULL is returned if no filter is found or allocation failed. 2204 */ 2205char * 2206tep_filter_make_string(struct tep_event_filter *filter, int event_id) 2207{ 2208 struct tep_filter_type *filter_type; 2209 2210 if (!filter->filters) 2211 return NULL; 2212 2213 filter_type = find_filter_type(filter, event_id); 2214 2215 if (!filter_type) 2216 return NULL; 2217 2218 return arg_to_str(filter, filter_type->filter); 2219} 2220 2221/** 2222 * tep_filter_compare - compare two filters and return if they are the same 2223 * @filter1: Filter to compare with @filter2 2224 * @filter2: Filter to compare with @filter1 2225 * 2226 * Returns: 2227 * 1 if the two filters hold the same content. 2228 * 0 if they do not. 2229 */ 2230int tep_filter_compare(struct tep_event_filter *filter1, struct tep_event_filter *filter2) 2231{ 2232 struct tep_filter_type *filter_type1; 2233 struct tep_filter_type *filter_type2; 2234 char *str1, *str2; 2235 int result; 2236 int i; 2237 2238 /* Do the easy checks first */ 2239 if (filter1->filters != filter2->filters) 2240 return 0; 2241 if (!filter1->filters && !filter2->filters) 2242 return 1; 2243 2244 /* 2245 * Now take a look at each of the events to see if they have the same 2246 * filters to them. 2247 */ 2248 for (i = 0; i < filter1->filters; i++) { 2249 filter_type1 = &filter1->event_filters[i]; 2250 filter_type2 = find_filter_type(filter2, filter_type1->event_id); 2251 if (!filter_type2) 2252 break; 2253 if (filter_type1->filter->type != filter_type2->filter->type) 2254 break; 2255 /* The best way to compare complex filters is with strings */ 2256 str1 = arg_to_str(filter1, filter_type1->filter); 2257 str2 = arg_to_str(filter2, filter_type2->filter); 2258 if (str1 && str2) 2259 result = strcmp(str1, str2) != 0; 2260 else 2261 /* bail out if allocation fails */ 2262 result = 1; 2263 2264 free(str1); 2265 free(str2); 2266 if (result) 2267 break; 2268 } 2269 2270 if (i < filter1->filters) 2271 return 0; 2272 return 1; 2273} 2274