at v5.2 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 return -1; 1478 1479 arg->type = TEP_FILTER_ARG_BOOLEAN; 1480 if (strcmp(str, "TRUE") == 0) 1481 arg->boolean.value = 1; 1482 else 1483 arg->boolean.value = 0; 1484 1485 filter_type = add_filter_type(filter, event->id); 1486 if (filter_type == NULL) 1487 return -1; 1488 1489 filter_type->filter = arg; 1490 1491 free(str); 1492 return 0; 1493 } 1494 1495 filter_event(filter, event, str, NULL); 1496 free(str); 1497 1498 return 0; 1499} 1500 1501/** 1502 * tep_filter_copy - copy a filter using another filter 1503 * @dest - the filter to copy to 1504 * @source - the filter to copy from 1505 * 1506 * Returns 0 on success and -1 if not all filters were copied 1507 */ 1508int tep_filter_copy(struct tep_event_filter *dest, struct tep_event_filter *source) 1509{ 1510 int ret = 0; 1511 int i; 1512 1513 tep_filter_reset(dest); 1514 1515 for (i = 0; i < source->filters; i++) { 1516 if (copy_filter_type(dest, source, &source->event_filters[i])) 1517 ret = -1; 1518 } 1519 return ret; 1520} 1521 1522static int test_filter(struct tep_event *event, struct tep_filter_arg *arg, 1523 struct tep_record *record, enum tep_errno *err); 1524 1525static const char * 1526get_comm(struct tep_event *event, struct tep_record *record) 1527{ 1528 const char *comm; 1529 int pid; 1530 1531 pid = tep_data_pid(event->tep, record); 1532 comm = tep_data_comm_from_pid(event->tep, pid); 1533 return comm; 1534} 1535 1536static unsigned long long 1537get_value(struct tep_event *event, 1538 struct tep_format_field *field, struct tep_record *record) 1539{ 1540 unsigned long long val; 1541 1542 /* Handle our dummy "comm" field */ 1543 if (field == &comm) { 1544 const char *name; 1545 1546 name = get_comm(event, record); 1547 return (unsigned long)name; 1548 } 1549 1550 /* Handle our dummy "cpu" field */ 1551 if (field == &cpu) 1552 return record->cpu; 1553 1554 tep_read_number_field(field, record->data, &val); 1555 1556 if (!(field->flags & TEP_FIELD_IS_SIGNED)) 1557 return val; 1558 1559 switch (field->size) { 1560 case 1: 1561 return (char)val; 1562 case 2: 1563 return (short)val; 1564 case 4: 1565 return (int)val; 1566 case 8: 1567 return (long long)val; 1568 } 1569 return val; 1570} 1571 1572static unsigned long long 1573get_arg_value(struct tep_event *event, struct tep_filter_arg *arg, 1574 struct tep_record *record, enum tep_errno *err); 1575 1576static unsigned long long 1577get_exp_value(struct tep_event *event, struct tep_filter_arg *arg, 1578 struct tep_record *record, enum tep_errno *err) 1579{ 1580 unsigned long long lval, rval; 1581 1582 lval = get_arg_value(event, arg->exp.left, record, err); 1583 rval = get_arg_value(event, arg->exp.right, record, err); 1584 1585 if (*err) { 1586 /* 1587 * There was an error, no need to process anymore. 1588 */ 1589 return 0; 1590 } 1591 1592 switch (arg->exp.type) { 1593 case TEP_FILTER_EXP_ADD: 1594 return lval + rval; 1595 1596 case TEP_FILTER_EXP_SUB: 1597 return lval - rval; 1598 1599 case TEP_FILTER_EXP_MUL: 1600 return lval * rval; 1601 1602 case TEP_FILTER_EXP_DIV: 1603 return lval / rval; 1604 1605 case TEP_FILTER_EXP_MOD: 1606 return lval % rval; 1607 1608 case TEP_FILTER_EXP_RSHIFT: 1609 return lval >> rval; 1610 1611 case TEP_FILTER_EXP_LSHIFT: 1612 return lval << rval; 1613 1614 case TEP_FILTER_EXP_AND: 1615 return lval & rval; 1616 1617 case TEP_FILTER_EXP_OR: 1618 return lval | rval; 1619 1620 case TEP_FILTER_EXP_XOR: 1621 return lval ^ rval; 1622 1623 case TEP_FILTER_EXP_NOT: 1624 default: 1625 if (!*err) 1626 *err = TEP_ERRNO__INVALID_EXP_TYPE; 1627 } 1628 return 0; 1629} 1630 1631static unsigned long long 1632get_arg_value(struct tep_event *event, struct tep_filter_arg *arg, 1633 struct tep_record *record, enum tep_errno *err) 1634{ 1635 switch (arg->type) { 1636 case TEP_FILTER_ARG_FIELD: 1637 return get_value(event, arg->field.field, record); 1638 1639 case TEP_FILTER_ARG_VALUE: 1640 if (arg->value.type != TEP_FILTER_NUMBER) { 1641 if (!*err) 1642 *err = TEP_ERRNO__NOT_A_NUMBER; 1643 } 1644 return arg->value.val; 1645 1646 case TEP_FILTER_ARG_EXP: 1647 return get_exp_value(event, arg, record, err); 1648 1649 default: 1650 if (!*err) 1651 *err = TEP_ERRNO__INVALID_ARG_TYPE; 1652 } 1653 return 0; 1654} 1655 1656static int test_num(struct tep_event *event, struct tep_filter_arg *arg, 1657 struct tep_record *record, enum tep_errno *err) 1658{ 1659 unsigned long long lval, rval; 1660 1661 lval = get_arg_value(event, arg->num.left, record, err); 1662 rval = get_arg_value(event, arg->num.right, record, err); 1663 1664 if (*err) { 1665 /* 1666 * There was an error, no need to process anymore. 1667 */ 1668 return 0; 1669 } 1670 1671 switch (arg->num.type) { 1672 case TEP_FILTER_CMP_EQ: 1673 return lval == rval; 1674 1675 case TEP_FILTER_CMP_NE: 1676 return lval != rval; 1677 1678 case TEP_FILTER_CMP_GT: 1679 return lval > rval; 1680 1681 case TEP_FILTER_CMP_LT: 1682 return lval < rval; 1683 1684 case TEP_FILTER_CMP_GE: 1685 return lval >= rval; 1686 1687 case TEP_FILTER_CMP_LE: 1688 return lval <= rval; 1689 1690 default: 1691 if (!*err) 1692 *err = TEP_ERRNO__ILLEGAL_INTEGER_CMP; 1693 return 0; 1694 } 1695} 1696 1697static const char *get_field_str(struct tep_filter_arg *arg, struct tep_record *record) 1698{ 1699 struct tep_event *event; 1700 struct tep_handle *tep; 1701 unsigned long long addr; 1702 const char *val = NULL; 1703 unsigned int size; 1704 char hex[64]; 1705 1706 /* If the field is not a string convert it */ 1707 if (arg->str.field->flags & TEP_FIELD_IS_STRING) { 1708 val = record->data + arg->str.field->offset; 1709 size = arg->str.field->size; 1710 1711 if (arg->str.field->flags & TEP_FIELD_IS_DYNAMIC) { 1712 addr = *(unsigned int *)val; 1713 val = record->data + (addr & 0xffff); 1714 size = addr >> 16; 1715 } 1716 1717 /* 1718 * We need to copy the data since we can't be sure the field 1719 * is null terminated. 1720 */ 1721 if (*(val + size - 1)) { 1722 /* copy it */ 1723 memcpy(arg->str.buffer, val, arg->str.field->size); 1724 /* the buffer is already NULL terminated */ 1725 val = arg->str.buffer; 1726 } 1727 1728 } else { 1729 event = arg->str.field->event; 1730 tep = event->tep; 1731 addr = get_value(event, arg->str.field, record); 1732 1733 if (arg->str.field->flags & (TEP_FIELD_IS_POINTER | TEP_FIELD_IS_LONG)) 1734 /* convert to a kernel symbol */ 1735 val = tep_find_function(tep, addr); 1736 1737 if (val == NULL) { 1738 /* just use the hex of the string name */ 1739 snprintf(hex, 64, "0x%llx", addr); 1740 val = hex; 1741 } 1742 } 1743 1744 return val; 1745} 1746 1747static int test_str(struct tep_event *event, struct tep_filter_arg *arg, 1748 struct tep_record *record, enum tep_errno *err) 1749{ 1750 const char *val; 1751 1752 if (arg->str.field == &comm) 1753 val = get_comm(event, record); 1754 else 1755 val = get_field_str(arg, record); 1756 1757 switch (arg->str.type) { 1758 case TEP_FILTER_CMP_MATCH: 1759 return strcmp(val, arg->str.val) == 0; 1760 1761 case TEP_FILTER_CMP_NOT_MATCH: 1762 return strcmp(val, arg->str.val) != 0; 1763 1764 case TEP_FILTER_CMP_REGEX: 1765 /* Returns zero on match */ 1766 return !regexec(&arg->str.reg, val, 0, NULL, 0); 1767 1768 case TEP_FILTER_CMP_NOT_REGEX: 1769 return regexec(&arg->str.reg, val, 0, NULL, 0); 1770 1771 default: 1772 if (!*err) 1773 *err = TEP_ERRNO__ILLEGAL_STRING_CMP; 1774 return 0; 1775 } 1776} 1777 1778static int test_op(struct tep_event *event, struct tep_filter_arg *arg, 1779 struct tep_record *record, enum tep_errno *err) 1780{ 1781 switch (arg->op.type) { 1782 case TEP_FILTER_OP_AND: 1783 return test_filter(event, arg->op.left, record, err) && 1784 test_filter(event, arg->op.right, record, err); 1785 1786 case TEP_FILTER_OP_OR: 1787 return test_filter(event, arg->op.left, record, err) || 1788 test_filter(event, arg->op.right, record, err); 1789 1790 case TEP_FILTER_OP_NOT: 1791 return !test_filter(event, arg->op.right, record, err); 1792 1793 default: 1794 if (!*err) 1795 *err = TEP_ERRNO__INVALID_OP_TYPE; 1796 return 0; 1797 } 1798} 1799 1800static int test_filter(struct tep_event *event, struct tep_filter_arg *arg, 1801 struct tep_record *record, enum tep_errno *err) 1802{ 1803 if (*err) { 1804 /* 1805 * There was an error, no need to process anymore. 1806 */ 1807 return 0; 1808 } 1809 1810 switch (arg->type) { 1811 case TEP_FILTER_ARG_BOOLEAN: 1812 /* easy case */ 1813 return arg->boolean.value; 1814 1815 case TEP_FILTER_ARG_OP: 1816 return test_op(event, arg, record, err); 1817 1818 case TEP_FILTER_ARG_NUM: 1819 return test_num(event, arg, record, err); 1820 1821 case TEP_FILTER_ARG_STR: 1822 return test_str(event, arg, record, err); 1823 1824 case TEP_FILTER_ARG_EXP: 1825 case TEP_FILTER_ARG_VALUE: 1826 case TEP_FILTER_ARG_FIELD: 1827 /* 1828 * Expressions, fields and values evaluate 1829 * to true if they return non zero 1830 */ 1831 return !!get_arg_value(event, arg, record, err); 1832 1833 default: 1834 if (!*err) 1835 *err = TEP_ERRNO__INVALID_ARG_TYPE; 1836 return 0; 1837 } 1838} 1839 1840/** 1841 * tep_event_filtered - return true if event has filter 1842 * @filter: filter struct with filter information 1843 * @event_id: event id to test if filter exists 1844 * 1845 * Returns 1 if filter found for @event_id 1846 * otherwise 0; 1847 */ 1848int tep_event_filtered(struct tep_event_filter *filter, int event_id) 1849{ 1850 struct tep_filter_type *filter_type; 1851 1852 if (!filter->filters) 1853 return 0; 1854 1855 filter_type = find_filter_type(filter, event_id); 1856 1857 return filter_type ? 1 : 0; 1858} 1859 1860/** 1861 * tep_filter_match - test if a record matches a filter 1862 * @filter: filter struct with filter information 1863 * @record: the record to test against the filter 1864 * 1865 * Returns: match result or error code (prefixed with TEP_ERRNO__) 1866 * FILTER_MATCH - filter found for event and @record matches 1867 * FILTER_MISS - filter found for event and @record does not match 1868 * FILTER_NOT_FOUND - no filter found for @record's event 1869 * NO_FILTER - if no filters exist 1870 * otherwise - error occurred during test 1871 */ 1872enum tep_errno tep_filter_match(struct tep_event_filter *filter, 1873 struct tep_record *record) 1874{ 1875 struct tep_handle *tep = filter->tep; 1876 struct tep_filter_type *filter_type; 1877 int event_id; 1878 int ret; 1879 enum tep_errno err = 0; 1880 1881 filter_init_error_buf(filter); 1882 1883 if (!filter->filters) 1884 return TEP_ERRNO__NO_FILTER; 1885 1886 event_id = tep_data_type(tep, record); 1887 1888 filter_type = find_filter_type(filter, event_id); 1889 if (!filter_type) 1890 return TEP_ERRNO__FILTER_NOT_FOUND; 1891 1892 ret = test_filter(filter_type->event, filter_type->filter, record, &err); 1893 if (err) 1894 return err; 1895 1896 return ret ? TEP_ERRNO__FILTER_MATCH : TEP_ERRNO__FILTER_MISS; 1897} 1898 1899static char *op_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 1900{ 1901 char *str = NULL; 1902 char *left = NULL; 1903 char *right = NULL; 1904 char *op = NULL; 1905 int left_val = -1; 1906 int right_val = -1; 1907 int val; 1908 1909 switch (arg->op.type) { 1910 case TEP_FILTER_OP_AND: 1911 op = "&&"; 1912 /* fall through */ 1913 case TEP_FILTER_OP_OR: 1914 if (!op) 1915 op = "||"; 1916 1917 left = arg_to_str(filter, arg->op.left); 1918 right = arg_to_str(filter, arg->op.right); 1919 if (!left || !right) 1920 break; 1921 1922 /* Try to consolidate boolean values */ 1923 if (strcmp(left, "TRUE") == 0) 1924 left_val = 1; 1925 else if (strcmp(left, "FALSE") == 0) 1926 left_val = 0; 1927 1928 if (strcmp(right, "TRUE") == 0) 1929 right_val = 1; 1930 else if (strcmp(right, "FALSE") == 0) 1931 right_val = 0; 1932 1933 if (left_val >= 0) { 1934 if ((arg->op.type == TEP_FILTER_OP_AND && !left_val) || 1935 (arg->op.type == TEP_FILTER_OP_OR && left_val)) { 1936 /* Just return left value */ 1937 str = left; 1938 left = NULL; 1939 break; 1940 } 1941 if (right_val >= 0) { 1942 /* just evaluate this. */ 1943 val = 0; 1944 switch (arg->op.type) { 1945 case TEP_FILTER_OP_AND: 1946 val = left_val && right_val; 1947 break; 1948 case TEP_FILTER_OP_OR: 1949 val = left_val || right_val; 1950 break; 1951 default: 1952 break; 1953 } 1954 asprintf(&str, val ? "TRUE" : "FALSE"); 1955 break; 1956 } 1957 } 1958 if (right_val >= 0) { 1959 if ((arg->op.type == TEP_FILTER_OP_AND && !right_val) || 1960 (arg->op.type == TEP_FILTER_OP_OR && right_val)) { 1961 /* Just return right value */ 1962 str = right; 1963 right = NULL; 1964 break; 1965 } 1966 /* The right value is meaningless */ 1967 str = left; 1968 left = NULL; 1969 break; 1970 } 1971 1972 asprintf(&str, "(%s) %s (%s)", left, op, right); 1973 break; 1974 1975 case TEP_FILTER_OP_NOT: 1976 op = "!"; 1977 right = arg_to_str(filter, arg->op.right); 1978 if (!right) 1979 break; 1980 1981 /* See if we can consolidate */ 1982 if (strcmp(right, "TRUE") == 0) 1983 right_val = 1; 1984 else if (strcmp(right, "FALSE") == 0) 1985 right_val = 0; 1986 if (right_val >= 0) { 1987 /* just return the opposite */ 1988 asprintf(&str, right_val ? "FALSE" : "TRUE"); 1989 break; 1990 } 1991 asprintf(&str, "%s(%s)", op, right); 1992 break; 1993 1994 default: 1995 /* ?? */ 1996 break; 1997 } 1998 free(left); 1999 free(right); 2000 return str; 2001} 2002 2003static char *val_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2004{ 2005 char *str = NULL; 2006 2007 asprintf(&str, "%lld", arg->value.val); 2008 2009 return str; 2010} 2011 2012static char *field_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2013{ 2014 return strdup(arg->field.field->name); 2015} 2016 2017static char *exp_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2018{ 2019 char *lstr; 2020 char *rstr; 2021 char *op; 2022 char *str = NULL; 2023 2024 lstr = arg_to_str(filter, arg->exp.left); 2025 rstr = arg_to_str(filter, arg->exp.right); 2026 if (!lstr || !rstr) 2027 goto out; 2028 2029 switch (arg->exp.type) { 2030 case TEP_FILTER_EXP_ADD: 2031 op = "+"; 2032 break; 2033 case TEP_FILTER_EXP_SUB: 2034 op = "-"; 2035 break; 2036 case TEP_FILTER_EXP_MUL: 2037 op = "*"; 2038 break; 2039 case TEP_FILTER_EXP_DIV: 2040 op = "/"; 2041 break; 2042 case TEP_FILTER_EXP_MOD: 2043 op = "%"; 2044 break; 2045 case TEP_FILTER_EXP_RSHIFT: 2046 op = ">>"; 2047 break; 2048 case TEP_FILTER_EXP_LSHIFT: 2049 op = "<<"; 2050 break; 2051 case TEP_FILTER_EXP_AND: 2052 op = "&"; 2053 break; 2054 case TEP_FILTER_EXP_OR: 2055 op = "|"; 2056 break; 2057 case TEP_FILTER_EXP_XOR: 2058 op = "^"; 2059 break; 2060 default: 2061 op = "[ERROR IN EXPRESSION TYPE]"; 2062 break; 2063 } 2064 2065 asprintf(&str, "%s %s %s", lstr, op, rstr); 2066out: 2067 free(lstr); 2068 free(rstr); 2069 2070 return str; 2071} 2072 2073static char *num_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2074{ 2075 char *lstr; 2076 char *rstr; 2077 char *str = NULL; 2078 char *op = NULL; 2079 2080 lstr = arg_to_str(filter, arg->num.left); 2081 rstr = arg_to_str(filter, arg->num.right); 2082 if (!lstr || !rstr) 2083 goto out; 2084 2085 switch (arg->num.type) { 2086 case TEP_FILTER_CMP_EQ: 2087 op = "=="; 2088 /* fall through */ 2089 case TEP_FILTER_CMP_NE: 2090 if (!op) 2091 op = "!="; 2092 /* fall through */ 2093 case TEP_FILTER_CMP_GT: 2094 if (!op) 2095 op = ">"; 2096 /* fall through */ 2097 case TEP_FILTER_CMP_LT: 2098 if (!op) 2099 op = "<"; 2100 /* fall through */ 2101 case TEP_FILTER_CMP_GE: 2102 if (!op) 2103 op = ">="; 2104 /* fall through */ 2105 case TEP_FILTER_CMP_LE: 2106 if (!op) 2107 op = "<="; 2108 2109 asprintf(&str, "%s %s %s", lstr, op, rstr); 2110 break; 2111 2112 default: 2113 /* ?? */ 2114 break; 2115 } 2116 2117out: 2118 free(lstr); 2119 free(rstr); 2120 return str; 2121} 2122 2123static char *str_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2124{ 2125 char *str = NULL; 2126 char *op = NULL; 2127 2128 switch (arg->str.type) { 2129 case TEP_FILTER_CMP_MATCH: 2130 op = "=="; 2131 /* fall through */ 2132 case TEP_FILTER_CMP_NOT_MATCH: 2133 if (!op) 2134 op = "!="; 2135 /* fall through */ 2136 case TEP_FILTER_CMP_REGEX: 2137 if (!op) 2138 op = "=~"; 2139 /* fall through */ 2140 case TEP_FILTER_CMP_NOT_REGEX: 2141 if (!op) 2142 op = "!~"; 2143 2144 asprintf(&str, "%s %s \"%s\"", 2145 arg->str.field->name, op, arg->str.val); 2146 break; 2147 2148 default: 2149 /* ?? */ 2150 break; 2151 } 2152 return str; 2153} 2154 2155static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg) 2156{ 2157 char *str = NULL; 2158 2159 switch (arg->type) { 2160 case TEP_FILTER_ARG_BOOLEAN: 2161 asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE"); 2162 return str; 2163 2164 case TEP_FILTER_ARG_OP: 2165 return op_to_str(filter, arg); 2166 2167 case TEP_FILTER_ARG_NUM: 2168 return num_to_str(filter, arg); 2169 2170 case TEP_FILTER_ARG_STR: 2171 return str_to_str(filter, arg); 2172 2173 case TEP_FILTER_ARG_VALUE: 2174 return val_to_str(filter, arg); 2175 2176 case TEP_FILTER_ARG_FIELD: 2177 return field_to_str(filter, arg); 2178 2179 case TEP_FILTER_ARG_EXP: 2180 return exp_to_str(filter, arg); 2181 2182 default: 2183 /* ?? */ 2184 return NULL; 2185 } 2186 2187} 2188 2189/** 2190 * tep_filter_make_string - return a string showing the filter 2191 * @filter: filter struct with filter information 2192 * @event_id: the event id to return the filter string with 2193 * 2194 * Returns a string that displays the filter contents. 2195 * This string must be freed with free(str). 2196 * NULL is returned if no filter is found or allocation failed. 2197 */ 2198char * 2199tep_filter_make_string(struct tep_event_filter *filter, int event_id) 2200{ 2201 struct tep_filter_type *filter_type; 2202 2203 if (!filter->filters) 2204 return NULL; 2205 2206 filter_type = find_filter_type(filter, event_id); 2207 2208 if (!filter_type) 2209 return NULL; 2210 2211 return arg_to_str(filter, filter_type->filter); 2212} 2213 2214/** 2215 * tep_filter_compare - compare two filters and return if they are the same 2216 * @filter1: Filter to compare with @filter2 2217 * @filter2: Filter to compare with @filter1 2218 * 2219 * Returns: 2220 * 1 if the two filters hold the same content. 2221 * 0 if they do not. 2222 */ 2223int tep_filter_compare(struct tep_event_filter *filter1, struct tep_event_filter *filter2) 2224{ 2225 struct tep_filter_type *filter_type1; 2226 struct tep_filter_type *filter_type2; 2227 char *str1, *str2; 2228 int result; 2229 int i; 2230 2231 /* Do the easy checks first */ 2232 if (filter1->filters != filter2->filters) 2233 return 0; 2234 if (!filter1->filters && !filter2->filters) 2235 return 1; 2236 2237 /* 2238 * Now take a look at each of the events to see if they have the same 2239 * filters to them. 2240 */ 2241 for (i = 0; i < filter1->filters; i++) { 2242 filter_type1 = &filter1->event_filters[i]; 2243 filter_type2 = find_filter_type(filter2, filter_type1->event_id); 2244 if (!filter_type2) 2245 break; 2246 if (filter_type1->filter->type != filter_type2->filter->type) 2247 break; 2248 /* The best way to compare complex filters is with strings */ 2249 str1 = arg_to_str(filter1, filter_type1->filter); 2250 str2 = arg_to_str(filter2, filter_type2->filter); 2251 if (str1 && str2) 2252 result = strcmp(str1, str2) != 0; 2253 else 2254 /* bail out if allocation fails */ 2255 result = 1; 2256 2257 free(str1); 2258 free(str2); 2259 if (result) 2260 break; 2261 } 2262 2263 if (i < filter1->filters) 2264 return 0; 2265 return 1; 2266} 2267