Specialize load and unary ops
[lttng-ust.git] / liblttng-ust / lttng-filter.c
1 /*
2 * lttng-filter.c
3 *
4 * LTTng UST filter code.
5 *
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <errno.h>
24 #include <stdio.h>
25 #include <helper.h>
26 #include <lttng/ust-events.h>
27 #include <stdint.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <inttypes.h>
31 #include <limits.h>
32 #include <usterr-signal-safe.h>
33 #include "filter-bytecode.h"
34
35 #define NR_REG 2
36
37 #ifndef min_t
38 #define min_t(type, a, b) \
39 ((type) (a) < (type) (b) ? (type) (a) : (type) (b))
40 #endif
41
42 #ifndef likely
43 #define likely(x) __builtin_expect(!!(x), 1)
44 #endif
45
46 #ifndef unlikely
47 #define unlikely(x) __builtin_expect(!!(x), 0)
48 #endif
49
50 #ifdef DEBUG
51 #define dbg_printf(fmt, args...) printf("[debug bytecode] " fmt, ## args)
52 #else
53 #define dbg_printf(fmt, args...) \
54 do { \
55 /* do nothing but check printf format */ \
56 if (0) \
57 printf("[debug bytecode] " fmt, ## args); \
58 } while (0)
59 #endif
60
61 /* Linked bytecode */
62 struct bytecode_runtime {
63 uint16_t len;
64 char data[0];
65 };
66
67 enum reg_type {
68 REG_S64,
69 REG_DOUBLE,
70 REG_STRING,
71 REG_TYPE_UNKNOWN,
72 };
73
74 /* Validation registers */
75 struct vreg {
76 enum reg_type type;
77 int literal; /* is string literal ? */
78 };
79
80 /* Execution registers */
81 struct reg {
82 enum reg_type type;
83 int64_t v;
84 double d;
85
86 const char *str;
87 size_t seq_len;
88 int literal; /* is string literal ? */
89 };
90
91 static const char *opnames[] = {
92 [ FILTER_OP_UNKNOWN ] = "UNKNOWN",
93
94 [ FILTER_OP_RETURN ] = "RETURN",
95
96 /* binary */
97 [ FILTER_OP_MUL ] = "MUL",
98 [ FILTER_OP_DIV ] = "DIV",
99 [ FILTER_OP_MOD ] = "MOD",
100 [ FILTER_OP_PLUS ] = "PLUS",
101 [ FILTER_OP_MINUS ] = "MINUS",
102 [ FILTER_OP_RSHIFT ] = "RSHIFT",
103 [ FILTER_OP_LSHIFT ] = "LSHIFT",
104 [ FILTER_OP_BIN_AND ] = "BIN_AND",
105 [ FILTER_OP_BIN_OR ] = "BIN_OR",
106 [ FILTER_OP_BIN_XOR ] = "BIN_XOR",
107 [ FILTER_OP_EQ ] = "EQ",
108 [ FILTER_OP_NE ] = "NE",
109 [ FILTER_OP_GT ] = "GT",
110 [ FILTER_OP_LT ] = "LT",
111 [ FILTER_OP_GE ] = "GE",
112 [ FILTER_OP_LE ] = "LE",
113
114 /* unary */
115 [ FILTER_OP_UNARY_PLUS ] = "UNARY_PLUS",
116 [ FILTER_OP_UNARY_MINUS ] = "UNARY_MINUS",
117 [ FILTER_OP_UNARY_NOT ] = "UNARY_NOT",
118
119 /* logical */
120 [ FILTER_OP_AND ] = "AND",
121 [ FILTER_OP_OR ] = "OR",
122
123 /* load */
124 [ FILTER_OP_LOAD_FIELD_REF ] = "LOAD_FIELD_REF",
125 [ FILTER_OP_LOAD_FIELD_REF_STRING ] = "LOAD_FIELD_REF_STRING",
126 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE ] = "LOAD_FIELD_REF_SEQUENCE",
127 [ FILTER_OP_LOAD_FIELD_REF_S64 ] = "LOAD_FIELD_REF_S64",
128 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE ] = "LOAD_FIELD_REF_DOUBLE",
129
130 [ FILTER_OP_LOAD_STRING ] = "LOAD_STRING",
131 [ FILTER_OP_LOAD_S64 ] = "LOAD_S64",
132 [ FILTER_OP_LOAD_DOUBLE ] = "LOAD_DOUBLE",
133 };
134
135 static
136 const char *print_op(enum filter_op op)
137 {
138 if (op >= NR_FILTER_OPS)
139 return "UNKNOWN";
140 else
141 return opnames[op];
142 }
143
144 /*
145 * -1: wildcard found.
146 * -2: unknown escape char.
147 * 0: normal char.
148 */
149
150 static
151 int parse_char(const char **p)
152 {
153 switch (**p) {
154 case '\\':
155 (*p)++;
156 switch (**p) {
157 case '\\':
158 case '*':
159 return 0;
160 default:
161 return -2;
162 }
163 case '*':
164 return -1;
165 default:
166 return 0;
167 }
168 }
169
170 static
171 int reg_strcmp(struct reg reg[NR_REG], const char *cmp_type)
172 {
173 const char *p = reg[REG_R0].str, *q = reg[REG_R1].str;
174 int ret;
175 int diff;
176
177 for (;;) {
178 int escaped_r0 = 0;
179
180 if (unlikely(p - reg[REG_R0].str > reg[REG_R0].seq_len || *p == '\0')) {
181 if (q - reg[REG_R1].str > reg[REG_R1].seq_len || *q == '\0')
182 diff = 0;
183 else
184 diff = -1;
185 break;
186 }
187 if (unlikely(q - reg[REG_R1].str > reg[REG_R1].seq_len || *q == '\0')) {
188 if (p - reg[REG_R0].str > reg[REG_R0].seq_len || *p == '\0')
189 diff = 0;
190 else
191 diff = 1;
192 break;
193 }
194 if (reg[REG_R0].literal) {
195 ret = parse_char(&p);
196 if (ret == -1) {
197 return 0;
198 } else if (ret == -2) {
199 escaped_r0 = 1;
200 }
201 /* else compare both char */
202 }
203 if (reg[REG_R1].literal) {
204 ret = parse_char(&q);
205 if (ret == -1) {
206 return 0;
207 } else if (ret == -2) {
208 if (!escaped_r0)
209 return -1;
210 } else {
211 if (escaped_r0)
212 return 1;
213 }
214 } else {
215 if (escaped_r0)
216 return 1;
217 }
218 diff = *p - *q;
219 if (diff != 0)
220 break;
221 p++;
222 q++;
223 }
224 return diff;
225 }
226
227 static
228 int lttng_filter_false(void *filter_data,
229 const char *filter_stack_data)
230 {
231 return 0;
232 }
233
234 static
235 int lttng_filter_interpret_bytecode(void *filter_data,
236 const char *filter_stack_data)
237 {
238 struct bytecode_runtime *bytecode = filter_data;
239 void *pc, *next_pc, *start_pc;
240 int ret = -EINVAL;
241 int retval = 0;
242 struct reg reg[NR_REG];
243
244 start_pc = &bytecode->data[0];
245 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
246 pc = next_pc) {
247 dbg_printf("Executing op %s (%u)\n",
248 print_op((unsigned int) *(filter_opcode_t *) pc),
249 (unsigned int) *(filter_opcode_t *) pc);
250 switch (*(filter_opcode_t *) pc) {
251 case FILTER_OP_UNKNOWN:
252 case FILTER_OP_LOAD_FIELD_REF:
253 default:
254 ERR("unknown bytecode op %u\n",
255 (unsigned int) *(filter_opcode_t *) pc);
256 ret = -EINVAL;
257 goto end;
258
259 case FILTER_OP_RETURN:
260 retval = !!reg[0].v;
261 ret = 0;
262 goto end;
263
264 /* binary */
265 case FILTER_OP_MUL:
266 case FILTER_OP_DIV:
267 case FILTER_OP_MOD:
268 case FILTER_OP_PLUS:
269 case FILTER_OP_MINUS:
270 case FILTER_OP_RSHIFT:
271 case FILTER_OP_LSHIFT:
272 case FILTER_OP_BIN_AND:
273 case FILTER_OP_BIN_OR:
274 case FILTER_OP_BIN_XOR:
275 ERR("unsupported bytecode op %u\n",
276 (unsigned int) *(filter_opcode_t *) pc);
277 ret = -EINVAL;
278 goto end;
279
280 case FILTER_OP_EQ:
281 {
282 switch (reg[REG_R0].type) {
283 default:
284 ERR("unknown register type\n");
285 ret = -EINVAL;
286 goto end;
287
288 case REG_STRING:
289 reg[REG_R0].v = (reg_strcmp(reg, "==") == 0);
290 break;
291 case REG_S64:
292 switch (reg[REG_R1].type) {
293 default:
294 ERR("unknown register type\n");
295 ret = -EINVAL;
296 goto end;
297
298 case REG_S64:
299 reg[REG_R0].v = (reg[REG_R0].v == reg[REG_R1].v);
300 break;
301 case REG_DOUBLE:
302 reg[REG_R0].v = (reg[REG_R0].v == reg[REG_R1].d);
303 break;
304 }
305 break;
306 case REG_DOUBLE:
307 switch (reg[REG_R1].type) {
308 default:
309 ERR("unknown register type\n");
310 ret = -EINVAL;
311 goto end;
312
313 case REG_S64:
314 reg[REG_R0].v = (reg[REG_R0].d == reg[REG_R1].v);
315 break;
316 case REG_DOUBLE:
317 reg[REG_R0].v = (reg[REG_R0].d == reg[REG_R1].d);
318 break;
319 }
320 break;
321 }
322 reg[REG_R0].type = REG_S64;
323 next_pc += sizeof(struct binary_op);
324 break;
325 }
326 case FILTER_OP_NE:
327 {
328 switch (reg[REG_R0].type) {
329 default:
330 ERR("unknown register type\n");
331 ret = -EINVAL;
332 goto end;
333
334 case REG_STRING:
335 reg[REG_R0].v = (reg_strcmp(reg, "!=") != 0);
336 break;
337 case REG_S64:
338 switch (reg[REG_R1].type) {
339 default:
340 ERR("unknown register type\n");
341 ret = -EINVAL;
342 goto end;
343
344 case REG_S64:
345 reg[REG_R0].v = (reg[REG_R0].v != reg[REG_R1].v);
346 break;
347 case REG_DOUBLE:
348 reg[REG_R0].v = (reg[REG_R0].v != reg[REG_R1].d);
349 break;
350 }
351 break;
352 case REG_DOUBLE:
353 switch (reg[REG_R1].type) {
354 default:
355 ERR("unknown register type\n");
356 ret = -EINVAL;
357 goto end;
358
359 case REG_S64:
360 reg[REG_R0].v = (reg[REG_R0].d != reg[REG_R1].v);
361 break;
362 case REG_DOUBLE:
363 reg[REG_R0].v = (reg[REG_R0].d != reg[REG_R1].d);
364 break;
365 }
366 break;
367 }
368 reg[REG_R0].type = REG_S64;
369 next_pc += sizeof(struct binary_op);
370 break;
371 }
372 case FILTER_OP_GT:
373 {
374 switch (reg[REG_R0].type) {
375 default:
376 ERR("unknown register type\n");
377 ret = -EINVAL;
378 goto end;
379
380 case REG_STRING:
381 reg[REG_R0].v = (reg_strcmp(reg, ">") > 0);
382 break;
383 case REG_S64:
384 switch (reg[REG_R1].type) {
385 default:
386 ERR("unknown register type\n");
387 ret = -EINVAL;
388 goto end;
389
390 case REG_S64:
391 reg[REG_R0].v = (reg[REG_R0].v > reg[REG_R1].v);
392 break;
393 case REG_DOUBLE:
394 reg[REG_R0].v = (reg[REG_R0].v > reg[REG_R1].d);
395 break;
396 }
397 break;
398 case REG_DOUBLE:
399 switch (reg[REG_R1].type) {
400 default:
401 ERR("unknown register type\n");
402 ret = -EINVAL;
403 goto end;
404
405 case REG_S64:
406 reg[REG_R0].v = (reg[REG_R0].d > reg[REG_R1].v);
407 break;
408 case REG_DOUBLE:
409 reg[REG_R0].v = (reg[REG_R0].d > reg[REG_R1].d);
410 break;
411 }
412 break;
413 }
414 reg[REG_R0].type = REG_S64;
415 next_pc += sizeof(struct binary_op);
416 break;
417 }
418 case FILTER_OP_LT:
419 {
420 switch (reg[REG_R0].type) {
421 default:
422 ERR("unknown register type\n");
423 ret = -EINVAL;
424 goto end;
425
426 case REG_STRING:
427 reg[REG_R0].v = (reg_strcmp(reg, "<") < 0);
428 break;
429 case REG_S64:
430 switch (reg[REG_R1].type) {
431 default:
432 ERR("unknown register type\n");
433 ret = -EINVAL;
434 goto end;
435
436 case REG_S64:
437 reg[REG_R0].v = (reg[REG_R0].v < reg[REG_R1].v);
438 break;
439 case REG_DOUBLE:
440 reg[REG_R0].v = (reg[REG_R0].v < reg[REG_R1].d);
441 break;
442 }
443 break;
444 case REG_DOUBLE:
445 switch (reg[REG_R1].type) {
446 default:
447 ERR("unknown register type\n");
448 ret = -EINVAL;
449 goto end;
450
451 case REG_S64:
452 reg[REG_R0].v = (reg[REG_R0].d < reg[REG_R1].v);
453 break;
454 case REG_DOUBLE:
455 reg[REG_R0].v = (reg[REG_R0].d < reg[REG_R1].d);
456 break;
457 }
458 break;
459 }
460 reg[REG_R0].type = REG_S64;
461 next_pc += sizeof(struct binary_op);
462 break;
463 }
464 case FILTER_OP_GE:
465 {
466 switch (reg[REG_R0].type) {
467 default:
468 ERR("unknown register type\n");
469 ret = -EINVAL;
470 goto end;
471
472 case REG_STRING:
473 reg[REG_R0].v = (reg_strcmp(reg, ">=") >= 0);
474 break;
475 case REG_S64:
476 switch (reg[REG_R1].type) {
477 default:
478 ERR("unknown register type\n");
479 ret = -EINVAL;
480 goto end;
481
482 case REG_S64:
483 reg[REG_R0].v = (reg[REG_R0].v >= reg[REG_R1].v);
484 break;
485 case REG_DOUBLE:
486 reg[REG_R0].v = (reg[REG_R0].v >= reg[REG_R1].d);
487 break;
488 }
489 break;
490 case REG_DOUBLE:
491 switch (reg[REG_R1].type) {
492 default:
493 ERR("unknown register type\n");
494 ret = -EINVAL;
495 goto end;
496
497 case REG_S64:
498 reg[REG_R0].v = (reg[REG_R0].d >= reg[REG_R1].v);
499 break;
500 case REG_DOUBLE:
501 reg[REG_R0].v = (reg[REG_R0].d >= reg[REG_R1].d);
502 break;
503 }
504 break;
505 }
506 reg[REG_R0].type = REG_S64;
507 next_pc += sizeof(struct binary_op);
508 break;
509 }
510 case FILTER_OP_LE:
511 {
512 switch (reg[REG_R0].type) {
513 default:
514 ERR("unknown register type\n");
515 ret = -EINVAL;
516 goto end;
517
518 case REG_STRING:
519 reg[REG_R0].v = (reg_strcmp(reg, "<=") <= 0);
520 break;
521 case REG_S64:
522 switch (reg[REG_R1].type) {
523 default:
524 ERR("unknown register type\n");
525 ret = -EINVAL;
526 goto end;
527
528 case REG_S64:
529 reg[REG_R0].v = (reg[REG_R0].v <= reg[REG_R1].v);
530 break;
531 case REG_DOUBLE:
532 reg[REG_R0].v = (reg[REG_R0].v <= reg[REG_R1].d);
533 break;
534 }
535 break;
536 case REG_DOUBLE:
537 switch (reg[REG_R1].type) {
538 default:
539 ERR("unknown register type\n");
540 ret = -EINVAL;
541 goto end;
542
543 case REG_S64:
544 reg[REG_R0].v = (reg[REG_R0].d <= reg[REG_R1].v);
545 break;
546 case REG_DOUBLE:
547 reg[REG_R0].v = (reg[REG_R0].d <= reg[REG_R1].d);
548 break;
549 }
550 break;
551 }
552 reg[REG_R0].type = REG_S64;
553 next_pc += sizeof(struct binary_op);
554 break;
555 }
556
557 /* unary */
558 case FILTER_OP_UNARY_PLUS:
559 {
560 next_pc += sizeof(struct unary_op);
561 break;
562 }
563 case FILTER_OP_UNARY_MINUS:
564 {
565 struct unary_op *insn = (struct unary_op *) pc;
566
567 switch (reg[insn->reg].type) {
568 default:
569 ERR("unknown register type\n");
570 ret = -EINVAL;
571 goto end;
572
573 case REG_STRING:
574 ERR("Unary minus can only be applied to numeric or floating point registers\n");
575 ret = -EINVAL;
576 goto end;
577 case REG_S64:
578 reg[insn->reg].v = -reg[insn->reg].v;
579 break;
580 case REG_DOUBLE:
581 reg[insn->reg].d = -reg[insn->reg].d;
582 break;
583 }
584 next_pc += sizeof(struct unary_op);
585 break;
586 }
587 case FILTER_OP_UNARY_NOT:
588 {
589 struct unary_op *insn = (struct unary_op *) pc;
590
591 switch (reg[insn->reg].type) {
592 default:
593 ERR("unknown register type\n");
594 ret = -EINVAL;
595 goto end;
596
597 case REG_STRING:
598 ERR("Unary not can only be applied to numeric or floating point registers\n");
599 ret = -EINVAL;
600 goto end;
601 case REG_S64:
602 reg[insn->reg].v = !reg[insn->reg].v;
603 break;
604 case REG_DOUBLE:
605 reg[insn->reg].d = !reg[insn->reg].d;
606 break;
607 }
608 reg[insn->reg].v = !reg[insn->reg].v;
609 next_pc += sizeof(struct unary_op);
610 break;
611 }
612 /* logical */
613 case FILTER_OP_AND:
614 {
615 struct logical_op *insn = (struct logical_op *) pc;
616
617 /* If REG_R0 is 0, skip and evaluate to 0 */
618 if ((reg[REG_R0].type == REG_S64 && reg[REG_R0].v == 0)
619 || (reg[REG_R0].type == REG_DOUBLE && reg[REG_R0].d == 0.0)) {
620 dbg_printf("Jumping to bytecode offset %u\n",
621 (unsigned int) insn->skip_offset);
622 next_pc = start_pc + insn->skip_offset;
623 } else {
624 next_pc += sizeof(struct logical_op);
625 }
626 break;
627 }
628 case FILTER_OP_OR:
629 {
630 struct logical_op *insn = (struct logical_op *) pc;
631
632 /* If REG_R0 is nonzero, skip and evaluate to 1 */
633
634 if ((reg[REG_R0].type == REG_S64 && reg[REG_R0].v != 0)
635 || (reg[REG_R0].type == REG_DOUBLE && reg[REG_R0].d != 0.0)) {
636 reg[REG_R0].v = 1;
637 dbg_printf("Jumping to bytecode offset %u\n",
638 (unsigned int) insn->skip_offset);
639 next_pc = start_pc + insn->skip_offset;
640 } else {
641 next_pc += sizeof(struct logical_op);
642 }
643 break;
644 }
645
646 /* load */
647 case FILTER_OP_LOAD_FIELD_REF_STRING:
648 {
649 struct load_op *insn = (struct load_op *) pc;
650 struct field_ref *ref = (struct field_ref *) insn->data;
651
652 dbg_printf("load field ref offset %u type string\n",
653 ref->offset);
654 reg[insn->reg].str =
655 *(const char * const *) &filter_stack_data[ref->offset];
656 reg[insn->reg].type = REG_STRING;
657 reg[insn->reg].seq_len = UINT_MAX;
658 reg[insn->reg].literal = 0;
659 dbg_printf("ref load string %s\n", reg[insn->reg].str);
660 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
661 break;
662 }
663
664 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
665 {
666 struct load_op *insn = (struct load_op *) pc;
667 struct field_ref *ref = (struct field_ref *) insn->data;
668
669 dbg_printf("load field ref offset %u type sequence\n",
670 ref->offset);
671 reg[insn->reg].seq_len =
672 *(unsigned long *) &filter_stack_data[ref->offset];
673 reg[insn->reg].str =
674 *(const char **) (&filter_stack_data[ref->offset
675 + sizeof(unsigned long)]);
676 reg[insn->reg].type = REG_STRING;
677 reg[insn->reg].literal = 0;
678 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
679 break;
680 }
681
682 case FILTER_OP_LOAD_FIELD_REF_S64:
683 {
684 struct load_op *insn = (struct load_op *) pc;
685 struct field_ref *ref = (struct field_ref *) insn->data;
686
687 dbg_printf("load field ref offset %u type s64\n",
688 ref->offset);
689 memcpy(&reg[insn->reg].v, &filter_stack_data[ref->offset],
690 sizeof(struct literal_numeric));
691 reg[insn->reg].type = REG_S64;
692 reg[insn->reg].literal = 0;
693 dbg_printf("ref load s64 %" PRIi64 "\n", reg[insn->reg].v);
694 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
695 break;
696 }
697
698 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
699 {
700 struct load_op *insn = (struct load_op *) pc;
701 struct field_ref *ref = (struct field_ref *) insn->data;
702
703 dbg_printf("load field ref offset %u type double\n",
704 ref->offset);
705 memcpy(&reg[insn->reg].d, &filter_stack_data[ref->offset],
706 sizeof(struct literal_double));
707 reg[insn->reg].type = REG_DOUBLE;
708 reg[insn->reg].literal = 0;
709 dbg_printf("ref load double %g\n", reg[insn->reg].d);
710 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
711 break;
712 }
713
714 case FILTER_OP_LOAD_STRING:
715 {
716 struct load_op *insn = (struct load_op *) pc;
717
718 dbg_printf("load string %s\n", insn->data);
719 reg[insn->reg].str = insn->data;
720 reg[insn->reg].type = REG_STRING;
721 reg[insn->reg].seq_len = UINT_MAX;
722 reg[insn->reg].literal = 1;
723 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
724 break;
725 }
726
727 case FILTER_OP_LOAD_S64:
728 {
729 struct load_op *insn = (struct load_op *) pc;
730
731 memcpy(&reg[insn->reg].v, insn->data,
732 sizeof(struct literal_numeric));
733 dbg_printf("load s64 %" PRIi64 "\n", reg[insn->reg].v);
734 reg[insn->reg].type = REG_S64;
735 reg[insn->reg].literal = 1;
736 next_pc += sizeof(struct load_op)
737 + sizeof(struct literal_numeric);
738 break;
739 }
740
741 case FILTER_OP_LOAD_DOUBLE:
742 {
743 struct load_op *insn = (struct load_op *) pc;
744
745 memcpy(&reg[insn->reg].d, insn->data,
746 sizeof(struct literal_double));
747 dbg_printf("load s64 %g\n", reg[insn->reg].d);
748 reg[insn->reg].type = REG_DOUBLE;
749 reg[insn->reg].literal = 1;
750 next_pc += sizeof(struct load_op)
751 + sizeof(struct literal_double);
752 break;
753 }
754 }
755 }
756 end:
757 /* return 0 (discard) on error */
758 if (ret)
759 return 0;
760 return retval;
761 }
762
763 static
764 int bin_op_compare_check(struct vreg reg[NR_REG], const char *str)
765 {
766 switch (reg[REG_R0].type) {
767 default:
768 goto error_unknown;
769
770 case REG_STRING:
771 switch (reg[REG_R1].type) {
772 default:
773 goto error_unknown;
774
775 case REG_STRING:
776 break;
777 case REG_S64:
778 case REG_DOUBLE:
779 goto error_mismatch;
780 }
781 break;
782 case REG_S64:
783 case REG_DOUBLE:
784 switch (reg[REG_R1].type) {
785 default:
786 goto error_unknown;
787
788 case REG_STRING:
789 goto error_mismatch;
790
791 case REG_S64:
792 case REG_DOUBLE:
793 break;
794 }
795 break;
796 }
797 return 0;
798
799 error_unknown:
800
801 return -EINVAL;
802 error_mismatch:
803 ERR("type mismatch for '%s' binary operator\n", str);
804 return -EINVAL;
805 }
806
807 static
808 int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode)
809 {
810 void *pc, *next_pc, *start_pc;
811 int ret = -EINVAL;
812 struct vreg reg[NR_REG];
813 int i;
814
815 for (i = 0; i < NR_REG; i++) {
816 reg[i].type = REG_TYPE_UNKNOWN;
817 reg[i].literal = 0;
818 }
819
820 start_pc = &bytecode->data[0];
821 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
822 pc = next_pc) {
823 if (unlikely(pc >= start_pc + bytecode->len)) {
824 ERR("filter bytecode overflow\n");
825 ret = -EINVAL;
826 goto end;
827 }
828 dbg_printf("Validating op %s (%u)\n",
829 print_op((unsigned int) *(filter_opcode_t *) pc),
830 (unsigned int) *(filter_opcode_t *) pc);
831 switch (*(filter_opcode_t *) pc) {
832 case FILTER_OP_UNKNOWN:
833 default:
834 ERR("unknown bytecode op %u\n",
835 (unsigned int) *(filter_opcode_t *) pc);
836 ret = -EINVAL;
837 goto end;
838
839 case FILTER_OP_RETURN:
840 ret = 0;
841 goto end;
842
843 /* binary */
844 case FILTER_OP_MUL:
845 case FILTER_OP_DIV:
846 case FILTER_OP_MOD:
847 case FILTER_OP_PLUS:
848 case FILTER_OP_MINUS:
849 case FILTER_OP_RSHIFT:
850 case FILTER_OP_LSHIFT:
851 case FILTER_OP_BIN_AND:
852 case FILTER_OP_BIN_OR:
853 case FILTER_OP_BIN_XOR:
854 ERR("unsupported bytecode op %u\n",
855 (unsigned int) *(filter_opcode_t *) pc);
856 ret = -EINVAL;
857 goto end;
858
859 case FILTER_OP_EQ:
860 {
861 ret = bin_op_compare_check(reg, "==");
862 if (ret)
863 goto end;
864 reg[REG_R0].type = REG_S64;
865 next_pc += sizeof(struct binary_op);
866 break;
867 }
868 case FILTER_OP_NE:
869 {
870 ret = bin_op_compare_check(reg, "!=");
871 if (ret)
872 goto end;
873 reg[REG_R0].type = REG_S64;
874 next_pc += sizeof(struct binary_op);
875 break;
876 }
877 case FILTER_OP_GT:
878 {
879 ret = bin_op_compare_check(reg, ">");
880 if (ret)
881 goto end;
882 reg[REG_R0].type = REG_S64;
883 next_pc += sizeof(struct binary_op);
884 break;
885 }
886 case FILTER_OP_LT:
887 {
888 ret = bin_op_compare_check(reg, "<");
889 if (ret)
890 goto end;
891 reg[REG_R0].type = REG_S64;
892 next_pc += sizeof(struct binary_op);
893 break;
894 }
895 case FILTER_OP_GE:
896 {
897 ret = bin_op_compare_check(reg, ">=");
898 if (ret)
899 goto end;
900 reg[REG_R0].type = REG_S64;
901 next_pc += sizeof(struct binary_op);
902 break;
903 }
904 case FILTER_OP_LE:
905 {
906 ret = bin_op_compare_check(reg, "<=");
907 if (ret)
908 goto end;
909 reg[REG_R0].type = REG_S64;
910 next_pc += sizeof(struct binary_op);
911 break;
912 }
913
914 /* unary */
915 case FILTER_OP_UNARY_PLUS:
916 case FILTER_OP_UNARY_MINUS:
917 case FILTER_OP_UNARY_NOT:
918 {
919 struct unary_op *insn = (struct unary_op *) pc;
920
921 if (unlikely(insn->reg >= REG_ERROR)) {
922 ERR("invalid register %u\n",
923 (unsigned int) insn->reg);
924 ret = -EINVAL;
925 goto end;
926 }
927 switch (reg[insn->reg].type) {
928 default:
929 ERR("unknown register type\n");
930 ret = -EINVAL;
931 goto end;
932
933 case REG_STRING:
934 ERR("Unary op can only be applied to numeric or floating point registers\n");
935 ret = -EINVAL;
936 goto end;
937 case REG_S64:
938 break;
939 case REG_DOUBLE:
940 break;
941 }
942 next_pc += sizeof(struct unary_op);
943 break;
944 }
945
946 case FILTER_OP_UNARY_PLUS_S64:
947 case FILTER_OP_UNARY_MINUS_S64:
948 case FILTER_OP_UNARY_NOT_S64:
949 {
950 struct unary_op *insn = (struct unary_op *) pc;
951
952 if (unlikely(insn->reg >= REG_ERROR)) {
953 ERR("invalid register %u\n",
954 (unsigned int) insn->reg);
955 ret = -EINVAL;
956 goto end;
957 }
958 if (reg[insn->reg].type != REG_S64) {
959 ERR("Invalid register type\n");
960 ret = -EINVAL;
961 goto end;
962 }
963 next_pc += sizeof(struct unary_op);
964 break;
965 }
966
967 case FILTER_OP_UNARY_PLUS_DOUBLE:
968 case FILTER_OP_UNARY_MINUS_DOUBLE:
969 case FILTER_OP_UNARY_NOT_DOUBLE:
970 {
971 struct unary_op *insn = (struct unary_op *) pc;
972
973 if (unlikely(insn->reg >= REG_ERROR)) {
974 ERR("invalid register %u\n",
975 (unsigned int) insn->reg);
976 ret = -EINVAL;
977 goto end;
978 }
979 if (reg[insn->reg].type != REG_DOUBLE) {
980 ERR("Invalid register type\n");
981 ret = -EINVAL;
982 goto end;
983 }
984 next_pc += sizeof(struct unary_op);
985 break;
986 }
987
988 /* logical */
989 case FILTER_OP_AND:
990 case FILTER_OP_OR:
991 {
992 struct logical_op *insn = (struct logical_op *) pc;
993
994 if (unlikely(reg[REG_R0].type == REG_TYPE_UNKNOWN
995 || reg[REG_R0].type == REG_TYPE_UNKNOWN
996 || reg[REG_R0].type == REG_STRING
997 || reg[REG_R1].type == REG_STRING)) {
998 ERR("Logical comparator can only be applied to numeric and floating point registers\n");
999 ret = -EINVAL;
1000 goto end;
1001 }
1002
1003 dbg_printf("Validate jumping to bytecode offset %u\n",
1004 (unsigned int) insn->skip_offset);
1005 if (unlikely(start_pc + insn->skip_offset <= pc)) {
1006 ERR("Loops are not allowed in bytecode\n");
1007 ret = -EINVAL;
1008 goto end;
1009 }
1010 next_pc += sizeof(struct logical_op);
1011 break;
1012 }
1013
1014 /* load */
1015 case FILTER_OP_LOAD_FIELD_REF:
1016 {
1017 ERR("Unknown field ref type\n");
1018 ret = -EINVAL;
1019 goto end;
1020 }
1021 case FILTER_OP_LOAD_FIELD_REF_STRING:
1022 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
1023 {
1024 struct load_op *insn = (struct load_op *) pc;
1025 struct field_ref *ref = (struct field_ref *) insn->data;
1026
1027 if (unlikely(insn->reg >= REG_ERROR)) {
1028 ERR("invalid register %u\n",
1029 (unsigned int) insn->reg);
1030 ret = -EINVAL;
1031 goto end;
1032 }
1033 dbg_printf("Validate load field ref offset %u type string\n",
1034 ref->offset);
1035 reg[insn->reg].type = REG_STRING;
1036 reg[insn->reg].literal = 0;
1037 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1038 break;
1039 }
1040 case FILTER_OP_LOAD_FIELD_REF_S64:
1041 {
1042 struct load_op *insn = (struct load_op *) pc;
1043 struct field_ref *ref = (struct field_ref *) insn->data;
1044
1045 if (unlikely(insn->reg >= REG_ERROR)) {
1046 ERR("invalid register %u\n",
1047 (unsigned int) insn->reg);
1048 ret = -EINVAL;
1049 goto end;
1050 }
1051 dbg_printf("Validate load field ref offset %u type s64\n",
1052 ref->offset);
1053 reg[insn->reg].type = REG_S64;
1054 reg[insn->reg].literal = 0;
1055 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1056 break;
1057 }
1058 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
1059 {
1060 struct load_op *insn = (struct load_op *) pc;
1061 struct field_ref *ref = (struct field_ref *) insn->data;
1062
1063 if (unlikely(insn->reg >= REG_ERROR)) {
1064 ERR("invalid register %u\n",
1065 (unsigned int) insn->reg);
1066 ret = -EINVAL;
1067 goto end;
1068 }
1069 dbg_printf("Validate load field ref offset %u type double\n",
1070 ref->offset);
1071 reg[insn->reg].type = REG_DOUBLE;
1072 reg[insn->reg].literal = 0;
1073 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1074 break;
1075 }
1076
1077 case FILTER_OP_LOAD_STRING:
1078 {
1079 struct load_op *insn = (struct load_op *) pc;
1080
1081 if (unlikely(insn->reg >= REG_ERROR)) {
1082 ERR("invalid register %u\n",
1083 (unsigned int) insn->reg);
1084 ret = -EINVAL;
1085 goto end;
1086 }
1087 reg[insn->reg].type = REG_STRING;
1088 reg[insn->reg].literal = 1;
1089 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1090 break;
1091 }
1092
1093 case FILTER_OP_LOAD_S64:
1094 {
1095 struct load_op *insn = (struct load_op *) pc;
1096
1097 if (unlikely(insn->reg >= REG_ERROR)) {
1098 ERR("invalid register %u\n",
1099 (unsigned int) insn->reg);
1100 ret = -EINVAL;
1101 goto end;
1102 }
1103 reg[insn->reg].type = REG_S64;
1104 reg[insn->reg].literal = 1;
1105 next_pc += sizeof(struct load_op)
1106 + sizeof(struct literal_numeric);
1107 break;
1108 }
1109
1110 case FILTER_OP_LOAD_DOUBLE:
1111 {
1112 struct load_op *insn = (struct load_op *) pc;
1113
1114 if (unlikely(insn->reg >= REG_ERROR)) {
1115 ERR("invalid register %u\n",
1116 (unsigned int) insn->reg);
1117 ret = -EINVAL;
1118 goto end;
1119 }
1120 reg[insn->reg].type = REG_DOUBLE;
1121 reg[insn->reg].literal = 1;
1122 next_pc += sizeof(struct load_op)
1123 + sizeof(struct literal_double);
1124 break;
1125 }
1126 }
1127 }
1128 end:
1129 return ret;
1130 }
1131
1132 static
1133 int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode)
1134 {
1135 void *pc, *next_pc, *start_pc;
1136 int ret = -EINVAL;
1137 struct vreg reg[NR_REG];
1138 int i;
1139
1140 for (i = 0; i < NR_REG; i++) {
1141 reg[i].type = REG_TYPE_UNKNOWN;
1142 reg[i].literal = 0;
1143 }
1144
1145 start_pc = &bytecode->data[0];
1146 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
1147 pc = next_pc) {
1148 switch (*(filter_opcode_t *) pc) {
1149 case FILTER_OP_UNKNOWN:
1150 default:
1151 ERR("unknown bytecode op %u\n",
1152 (unsigned int) *(filter_opcode_t *) pc);
1153 ret = -EINVAL;
1154 goto end;
1155
1156 case FILTER_OP_RETURN:
1157 ret = 0;
1158 goto end;
1159
1160 /* binary */
1161 case FILTER_OP_MUL:
1162 case FILTER_OP_DIV:
1163 case FILTER_OP_MOD:
1164 case FILTER_OP_PLUS:
1165 case FILTER_OP_MINUS:
1166 case FILTER_OP_RSHIFT:
1167 case FILTER_OP_LSHIFT:
1168 case FILTER_OP_BIN_AND:
1169 case FILTER_OP_BIN_OR:
1170 case FILTER_OP_BIN_XOR:
1171 ERR("unsupported bytecode op %u\n",
1172 (unsigned int) *(filter_opcode_t *) pc);
1173 ret = -EINVAL;
1174 goto end;
1175
1176 case FILTER_OP_EQ:
1177 case FILTER_OP_NE:
1178 case FILTER_OP_GT:
1179 case FILTER_OP_LT:
1180 case FILTER_OP_GE:
1181 case FILTER_OP_LE:
1182 {
1183 reg[REG_R0].type = REG_S64;
1184 next_pc += sizeof(struct binary_op);
1185 break;
1186 }
1187
1188 /* unary */
1189 case FILTER_OP_UNARY_PLUS:
1190 {
1191 struct unary_op *insn = (struct unary_op *) pc;
1192
1193 switch(reg[insn->reg].type) {
1194 default:
1195 ERR("unknown register type\n");
1196 ret = -EINVAL;
1197 goto end;
1198
1199 case REG_S64:
1200 insn->op = FILTER_OP_UNARY_PLUS_S64;
1201 break;
1202 case REG_DOUBLE:
1203 insn->op = FILTER_OP_UNARY_PLUS_DOUBLE;
1204 break;
1205 }
1206 break;
1207 }
1208
1209 case FILTER_OP_UNARY_MINUS:
1210 {
1211 struct unary_op *insn = (struct unary_op *) pc;
1212
1213 switch(reg[insn->reg].type) {
1214 default:
1215 ERR("unknown register type\n");
1216 ret = -EINVAL;
1217 goto end;
1218
1219 case REG_S64:
1220 insn->op = FILTER_OP_UNARY_MINUS_S64;
1221 break;
1222 case REG_DOUBLE:
1223 insn->op = FILTER_OP_UNARY_MINUS_DOUBLE;
1224 break;
1225 }
1226 break;
1227 }
1228
1229 case FILTER_OP_UNARY_NOT:
1230 {
1231 struct unary_op *insn = (struct unary_op *) pc;
1232
1233 switch(reg[insn->reg].type) {
1234 default:
1235 ERR("unknown register type\n");
1236 ret = -EINVAL;
1237 goto end;
1238
1239 case REG_S64:
1240 insn->op = FILTER_OP_UNARY_NOT_S64;
1241 break;
1242 case REG_DOUBLE:
1243 insn->op = FILTER_OP_UNARY_NOT_DOUBLE;
1244 break;
1245 }
1246 break;
1247 }
1248
1249 case FILTER_OP_UNARY_PLUS_S64:
1250 case FILTER_OP_UNARY_MINUS_S64:
1251 case FILTER_OP_UNARY_NOT_S64:
1252 case FILTER_OP_UNARY_PLUS_DOUBLE:
1253 case FILTER_OP_UNARY_MINUS_DOUBLE:
1254 case FILTER_OP_UNARY_NOT_DOUBLE:
1255 {
1256 next_pc += sizeof(struct unary_op);
1257 break;
1258 }
1259
1260 /* logical */
1261 case FILTER_OP_AND:
1262 case FILTER_OP_OR:
1263 {
1264 next_pc += sizeof(struct logical_op);
1265 break;
1266 }
1267
1268 /* load */
1269 case FILTER_OP_LOAD_FIELD_REF:
1270 {
1271 ERR("Unknown field ref type\n");
1272 ret = -EINVAL;
1273 goto end;
1274 }
1275 case FILTER_OP_LOAD_FIELD_REF_STRING:
1276 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
1277 {
1278 struct load_op *insn = (struct load_op *) pc;
1279
1280 reg[insn->reg].type = REG_STRING;
1281 reg[insn->reg].literal = 0;
1282 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1283 break;
1284 }
1285 case FILTER_OP_LOAD_FIELD_REF_S64:
1286 {
1287 struct load_op *insn = (struct load_op *) pc;
1288
1289 reg[insn->reg].type = REG_S64;
1290 reg[insn->reg].literal = 0;
1291 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1292 break;
1293 }
1294 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
1295 {
1296 struct load_op *insn = (struct load_op *) pc;
1297
1298 reg[insn->reg].type = REG_DOUBLE;
1299 reg[insn->reg].literal = 0;
1300 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1301 break;
1302 }
1303
1304 case FILTER_OP_LOAD_STRING:
1305 {
1306 struct load_op *insn = (struct load_op *) pc;
1307
1308 reg[insn->reg].type = REG_STRING;
1309 reg[insn->reg].literal = 1;
1310 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1311 break;
1312 }
1313
1314 case FILTER_OP_LOAD_S64:
1315 {
1316 struct load_op *insn = (struct load_op *) pc;
1317
1318 reg[insn->reg].type = REG_S64;
1319 reg[insn->reg].literal = 1;
1320 next_pc += sizeof(struct load_op)
1321 + sizeof(struct literal_numeric);
1322 break;
1323 }
1324
1325 case FILTER_OP_LOAD_DOUBLE:
1326 {
1327 struct load_op *insn = (struct load_op *) pc;
1328
1329 reg[insn->reg].type = REG_DOUBLE;
1330 reg[insn->reg].literal = 1;
1331 next_pc += sizeof(struct load_op)
1332 + sizeof(struct literal_double);
1333 break;
1334 }
1335 }
1336 }
1337 end:
1338 return ret;
1339 }
1340
1341
1342
1343 static
1344 int apply_field_reloc(struct ltt_event *event,
1345 struct bytecode_runtime *runtime,
1346 uint32_t runtime_len,
1347 uint32_t reloc_offset,
1348 const char *field_name)
1349 {
1350 const struct lttng_event_desc *desc;
1351 const struct lttng_event_field *fields, *field = NULL;
1352 unsigned int nr_fields, i;
1353 struct field_ref *field_ref;
1354 struct load_op *op;
1355 uint32_t field_offset = 0;
1356
1357 dbg_printf("Apply reloc: %u %s\n", reloc_offset, field_name);
1358
1359 /* Ensure that the reloc is within the code */
1360 if (runtime_len - reloc_offset < sizeof(uint16_t))
1361 return -EINVAL;
1362
1363 /* Lookup event by name */
1364 desc = event->desc;
1365 if (!desc)
1366 return -EINVAL;
1367 fields = desc->fields;
1368 if (!fields)
1369 return -EINVAL;
1370 nr_fields = desc->nr_fields;
1371 for (i = 0; i < nr_fields; i++) {
1372 if (!strcmp(fields[i].name, field_name)) {
1373 field = &fields[i];
1374 break;
1375 }
1376 /* compute field offset */
1377 switch (fields[i].type.atype) {
1378 case atype_integer:
1379 case atype_enum:
1380 field_offset += sizeof(int64_t);
1381 break;
1382 case atype_array:
1383 case atype_sequence:
1384 field_offset += sizeof(unsigned long);
1385 field_offset += sizeof(void *);
1386 break;
1387 case atype_string:
1388 field_offset += sizeof(void *);
1389 break;
1390 case atype_float:
1391 field_offset += sizeof(double);
1392 break;
1393 default:
1394 return -EINVAL;
1395 }
1396 }
1397 if (!field)
1398 return -EINVAL;
1399
1400 /* Check if field offset is too large for 16-bit offset */
1401 if (field_offset > FILTER_BYTECODE_MAX_LEN)
1402 return -EINVAL;
1403
1404 /* set type */
1405 op = (struct load_op *) &runtime->data[reloc_offset];
1406 field_ref = (struct field_ref *) op->data;
1407 switch (field->type.atype) {
1408 case atype_integer:
1409 case atype_enum:
1410 op->op = FILTER_OP_LOAD_FIELD_REF_S64;
1411 break;
1412 case atype_array:
1413 case atype_sequence:
1414 op->op = FILTER_OP_LOAD_FIELD_REF_SEQUENCE;
1415 break;
1416 case atype_string:
1417 op->op = FILTER_OP_LOAD_FIELD_REF_STRING;
1418 break;
1419 case atype_float:
1420 op->op = FILTER_OP_LOAD_FIELD_REF_DOUBLE;
1421 break;
1422 default:
1423 return -EINVAL;
1424 }
1425 /* set offset */
1426 field_ref->offset = (uint16_t) field_offset;
1427 return 0;
1428 }
1429
1430 /*
1431 * Take a bytecode with reloc table and link it to an event to create a
1432 * bytecode runtime.
1433 */
1434 static
1435 int _lttng_filter_event_link_bytecode(struct ltt_event *event,
1436 struct lttng_ust_filter_bytecode *filter_bytecode)
1437 {
1438 int ret, offset, next_offset;
1439 struct bytecode_runtime *runtime = NULL;
1440 size_t runtime_alloc_len;
1441
1442 if (!filter_bytecode)
1443 return 0;
1444 /* Even is not connected to any description */
1445 if (!event->desc)
1446 return 0;
1447 /* Bytecode already linked */
1448 if (event->filter || event->filter_data)
1449 return 0;
1450
1451 dbg_printf("Linking\n");
1452
1453 /* We don't need the reloc table in the runtime */
1454 runtime_alloc_len = sizeof(*runtime) + filter_bytecode->reloc_offset;
1455 runtime = zmalloc(runtime_alloc_len);
1456 if (!runtime) {
1457 ret = -ENOMEM;
1458 goto link_error;
1459 }
1460 runtime->len = filter_bytecode->reloc_offset;
1461 /* copy original bytecode */
1462 memcpy(runtime->data, filter_bytecode->data, runtime->len);
1463 /*
1464 * apply relocs. Those are a uint16_t (offset in bytecode)
1465 * followed by a string (field name).
1466 */
1467 for (offset = filter_bytecode->reloc_offset;
1468 offset < filter_bytecode->len;
1469 offset = next_offset) {
1470 uint16_t reloc_offset =
1471 *(uint16_t *) &filter_bytecode->data[offset];
1472 const char *field_name =
1473 (const char *) &filter_bytecode->data[offset + sizeof(uint16_t)];
1474
1475 ret = apply_field_reloc(event, runtime, runtime->len, reloc_offset, field_name);
1476 if (ret) {
1477 goto link_error;
1478 }
1479 next_offset = offset + sizeof(uint16_t) + strlen(field_name) + 1;
1480 }
1481 /* Validate bytecode */
1482 ret = lttng_filter_validate_bytecode(runtime);
1483 if (ret) {
1484 goto link_error;
1485 }
1486 /* Specialize bytecode */
1487 ret = lttng_filter_specialize_bytecode(runtime);
1488 if (ret) {
1489 goto link_error;
1490 }
1491 event->filter_data = runtime;
1492 event->filter = lttng_filter_interpret_bytecode;
1493 return 0;
1494
1495 link_error:
1496 event->filter = lttng_filter_false;
1497 free(runtime);
1498 return ret;
1499 }
1500
1501 void lttng_filter_event_link_bytecode(struct ltt_event *event,
1502 struct lttng_ust_filter_bytecode *filter_bytecode)
1503 {
1504 int ret;
1505
1506 ret = _lttng_filter_event_link_bytecode(event, filter_bytecode);
1507 if (ret) {
1508 fprintf(stderr, "[lttng filter] error linking event bytecode\n");
1509 }
1510 }
1511
1512 /*
1513 * Link bytecode to all events for a wildcard. Skips events that already
1514 * have a bytecode linked.
1515 * We do not set each event's filter_bytecode field, because they do not
1516 * own the filter_bytecode: the wildcard owns it.
1517 */
1518 void lttng_filter_wildcard_link_bytecode(struct session_wildcard *wildcard)
1519 {
1520 struct ltt_event *event;
1521 int ret;
1522
1523 if (!wildcard->filter_bytecode)
1524 return;
1525
1526 cds_list_for_each_entry(event, &wildcard->events, wildcard_list) {
1527 if (event->filter)
1528 continue;
1529 ret = _lttng_filter_event_link_bytecode(event,
1530 wildcard->filter_bytecode);
1531 if (ret) {
1532 fprintf(stderr, "[lttng filter] error linking wildcard bytecode\n");
1533 }
1534
1535 }
1536 return;
1537 }
1538
1539 /*
1540 * Need to attach filter to an event before starting tracing for the
1541 * session. We own the filter_bytecode if we return success.
1542 */
1543 int lttng_filter_event_attach_bytecode(struct ltt_event *event,
1544 struct lttng_ust_filter_bytecode *filter_bytecode)
1545 {
1546 if (event->chan->session->been_active)
1547 return -EPERM;
1548 if (event->filter_bytecode)
1549 return -EEXIST;
1550 event->filter_bytecode = filter_bytecode;
1551 return 0;
1552 }
1553
1554 /*
1555 * Need to attach filter to a wildcard before starting tracing for the
1556 * session. We own the filter_bytecode if we return success.
1557 */
1558 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard *wildcard,
1559 struct lttng_ust_filter_bytecode *filter_bytecode)
1560 {
1561 if (wildcard->chan->session->been_active)
1562 return -EPERM;
1563 if (wildcard->filter_bytecode)
1564 return -EEXIST;
1565 wildcard->filter_bytecode = filter_bytecode;
1566 return 0;
1567 }
This page took 0.079726 seconds and 5 git commands to generate.