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