Remove redundant validation from interpreter
[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 };
72
73 /* Validation registers */
74 struct vreg {
75 enum reg_type type;
76 int literal; /* is string literal ? */
77 };
78
79 /* Execution registers */
80 struct reg {
81 enum reg_type type;
82 int64_t v;
83 double d;
84
85 const char *str;
86 size_t seq_len;
87 int literal; /* is string literal ? */
88 };
89
90 static const char *opnames[] = {
91 [ FILTER_OP_UNKNOWN ] = "UNKNOWN",
92
93 [ FILTER_OP_RETURN ] = "RETURN",
94
95 /* binary */
96 [ FILTER_OP_MUL ] = "MUL",
97 [ FILTER_OP_DIV ] = "DIV",
98 [ FILTER_OP_MOD ] = "MOD",
99 [ FILTER_OP_PLUS ] = "PLUS",
100 [ FILTER_OP_MINUS ] = "MINUS",
101 [ FILTER_OP_RSHIFT ] = "RSHIFT",
102 [ FILTER_OP_LSHIFT ] = "LSHIFT",
103 [ FILTER_OP_BIN_AND ] = "BIN_AND",
104 [ FILTER_OP_BIN_OR ] = "BIN_OR",
105 [ FILTER_OP_BIN_XOR ] = "BIN_XOR",
106 [ FILTER_OP_EQ ] = "EQ",
107 [ FILTER_OP_NE ] = "NE",
108 [ FILTER_OP_GT ] = "GT",
109 [ FILTER_OP_LT ] = "LT",
110 [ FILTER_OP_GE ] = "GE",
111 [ FILTER_OP_LE ] = "LE",
112
113 /* unary */
114 [ FILTER_OP_UNARY_PLUS ] = "UNARY_PLUS",
115 [ FILTER_OP_UNARY_MINUS ] = "UNARY_MINUS",
116 [ FILTER_OP_UNARY_NOT ] = "UNARY_NOT",
117
118 /* logical */
119 [ FILTER_OP_AND ] = "AND",
120 [ FILTER_OP_OR ] = "OR",
121
122 /* load */
123 [ FILTER_OP_LOAD_FIELD_REF ] = "LOAD_FIELD_REF",
124 [ FILTER_OP_LOAD_STRING ] = "LOAD_STRING",
125 [ FILTER_OP_LOAD_S64 ] = "LOAD_S64",
126 [ FILTER_OP_LOAD_DOUBLE ] = "LOAD_DOUBLE",
127 };
128
129 static
130 const char *print_op(enum filter_op op)
131 {
132 if (op >= NR_FILTER_OPS)
133 return "UNKNOWN";
134 else
135 return opnames[op];
136 }
137
138 /*
139 * -1: wildcard found.
140 * -2: unknown escape char.
141 * 0: normal char.
142 */
143
144 static
145 int parse_char(const char **p)
146 {
147 switch (**p) {
148 case '\\':
149 (*p)++;
150 switch (**p) {
151 case '\\':
152 case '*':
153 return 0;
154 default:
155 return -2;
156 }
157 case '*':
158 return -1;
159 default:
160 return 0;
161 }
162 }
163
164 static
165 int reg_strcmp(struct reg reg[NR_REG], const char *cmp_type)
166 {
167 const char *p = reg[REG_R0].str, *q = reg[REG_R1].str;
168 int ret;
169 int diff;
170
171 for (;;) {
172 int escaped_r0 = 0;
173
174 if (unlikely(p - reg[REG_R0].str > reg[REG_R0].seq_len || *p == '\0')) {
175 if (q - reg[REG_R1].str > reg[REG_R1].seq_len || *q == '\0')
176 diff = 0;
177 else
178 diff = -1;
179 break;
180 }
181 if (unlikely(q - reg[REG_R1].str > reg[REG_R1].seq_len || *q == '\0')) {
182 if (p - reg[REG_R0].str > reg[REG_R0].seq_len || *p == '\0')
183 diff = 0;
184 else
185 diff = 1;
186 break;
187 }
188 if (reg[REG_R0].literal) {
189 ret = parse_char(&p);
190 if (ret == -1) {
191 return 0;
192 } else if (ret == -2) {
193 escaped_r0 = 1;
194 }
195 /* else compare both char */
196 }
197 if (reg[REG_R1].literal) {
198 ret = parse_char(&q);
199 if (ret == -1) {
200 return 0;
201 } else if (ret == -2) {
202 if (!escaped_r0)
203 return -1;
204 } else {
205 if (escaped_r0)
206 return 1;
207 }
208 } else {
209 if (escaped_r0)
210 return 1;
211 }
212 diff = *p - *q;
213 if (diff != 0)
214 break;
215 p++;
216 q++;
217 }
218 return diff;
219 }
220
221 static
222 int lttng_filter_false(void *filter_data,
223 const char *filter_stack_data)
224 {
225 return 0;
226 }
227
228 static
229 int lttng_filter_interpret_bytecode(void *filter_data,
230 const char *filter_stack_data)
231 {
232 struct bytecode_runtime *bytecode = filter_data;
233 void *pc, *next_pc, *start_pc;
234 int ret = -EINVAL;
235 int retval = 0;
236 struct reg reg[NR_REG];
237 int i;
238
239 for (i = 0; i < NR_REG; i++) {
240 reg[i].type = REG_S64;
241 reg[i].v = 0;
242 reg[i].d = 0.0;
243 reg[i].str = NULL;
244 reg[i].seq_len = 0;
245 reg[i].literal = 0;
246 }
247
248 start_pc = &bytecode->data[0];
249 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
250 pc = next_pc) {
251 dbg_printf("Executing op %s (%u)\n",
252 print_op((unsigned int) *(filter_opcode_t *) pc),
253 (unsigned int) *(filter_opcode_t *) pc);
254 switch (*(filter_opcode_t *) pc) {
255 case FILTER_OP_UNKNOWN:
256 default:
257 ERR("unknown bytecode op %u\n",
258 (unsigned int) *(filter_opcode_t *) pc);
259 ret = -EINVAL;
260 goto end;
261
262 case FILTER_OP_RETURN:
263 retval = !!reg[0].v;
264 ret = 0;
265 goto end;
266
267 /* binary */
268 case FILTER_OP_MUL:
269 case FILTER_OP_DIV:
270 case FILTER_OP_MOD:
271 case FILTER_OP_PLUS:
272 case FILTER_OP_MINUS:
273 case FILTER_OP_RSHIFT:
274 case FILTER_OP_LSHIFT:
275 case FILTER_OP_BIN_AND:
276 case FILTER_OP_BIN_OR:
277 case FILTER_OP_BIN_XOR:
278 ERR("unsupported bytecode op %u\n",
279 (unsigned int) *(filter_opcode_t *) pc);
280 ret = -EINVAL;
281 goto end;
282
283 case FILTER_OP_EQ:
284 {
285 switch (reg[REG_R0].type) {
286 default:
287 ERR("unknown register type\n");
288 ret = -EINVAL;
289 goto end;
290
291 case REG_STRING:
292 reg[REG_R0].v = (reg_strcmp(reg, "==") == 0);
293 break;
294 case REG_S64:
295 switch (reg[REG_R1].type) {
296 default:
297 ERR("unknown register type\n");
298 ret = -EINVAL;
299 goto end;
300
301 case REG_S64:
302 reg[REG_R0].v = (reg[REG_R0].v == reg[REG_R1].v);
303 break;
304 case REG_DOUBLE:
305 reg[REG_R0].v = (reg[REG_R0].v == reg[REG_R1].d);
306 break;
307 }
308 break;
309 case REG_DOUBLE:
310 switch (reg[REG_R1].type) {
311 default:
312 ERR("unknown register type\n");
313 ret = -EINVAL;
314 goto end;
315
316 case REG_S64:
317 reg[REG_R0].v = (reg[REG_R0].d == reg[REG_R1].v);
318 break;
319 case REG_DOUBLE:
320 reg[REG_R0].v = (reg[REG_R0].d == reg[REG_R1].d);
321 break;
322 }
323 break;
324 }
325 reg[REG_R0].type = REG_S64;
326 next_pc += sizeof(struct binary_op);
327 break;
328 }
329 case FILTER_OP_NE:
330 {
331 switch (reg[REG_R0].type) {
332 default:
333 ERR("unknown register type\n");
334 ret = -EINVAL;
335 goto end;
336
337 case REG_STRING:
338 reg[REG_R0].v = (reg_strcmp(reg, "!=") != 0);
339 break;
340 case REG_S64:
341 switch (reg[REG_R1].type) {
342 default:
343 ERR("unknown register type\n");
344 ret = -EINVAL;
345 goto end;
346
347 case REG_S64:
348 reg[REG_R0].v = (reg[REG_R0].v != reg[REG_R1].v);
349 break;
350 case REG_DOUBLE:
351 reg[REG_R0].v = (reg[REG_R0].v != reg[REG_R1].d);
352 break;
353 }
354 break;
355 case REG_DOUBLE:
356 switch (reg[REG_R1].type) {
357 default:
358 ERR("unknown register type\n");
359 ret = -EINVAL;
360 goto end;
361
362 case REG_S64:
363 reg[REG_R0].v = (reg[REG_R0].d != reg[REG_R1].v);
364 break;
365 case REG_DOUBLE:
366 reg[REG_R0].v = (reg[REG_R0].d != reg[REG_R1].d);
367 break;
368 }
369 break;
370 }
371 reg[REG_R0].type = REG_S64;
372 next_pc += sizeof(struct binary_op);
373 break;
374 }
375 case FILTER_OP_GT:
376 {
377 switch (reg[REG_R0].type) {
378 default:
379 ERR("unknown register type\n");
380 ret = -EINVAL;
381 goto end;
382
383 case REG_STRING:
384 reg[REG_R0].v = (reg_strcmp(reg, ">") > 0);
385 break;
386 case REG_S64:
387 switch (reg[REG_R1].type) {
388 default:
389 ERR("unknown register type\n");
390 ret = -EINVAL;
391 goto end;
392
393 case REG_S64:
394 reg[REG_R0].v = (reg[REG_R0].v > reg[REG_R1].v);
395 break;
396 case REG_DOUBLE:
397 reg[REG_R0].v = (reg[REG_R0].v > reg[REG_R1].d);
398 break;
399 }
400 break;
401 case REG_DOUBLE:
402 switch (reg[REG_R1].type) {
403 default:
404 ERR("unknown register type\n");
405 ret = -EINVAL;
406 goto end;
407
408 case REG_S64:
409 reg[REG_R0].v = (reg[REG_R0].d > reg[REG_R1].v);
410 break;
411 case REG_DOUBLE:
412 reg[REG_R0].v = (reg[REG_R0].d > reg[REG_R1].d);
413 break;
414 }
415 break;
416 }
417 reg[REG_R0].type = REG_S64;
418 next_pc += sizeof(struct binary_op);
419 break;
420 }
421 case FILTER_OP_LT:
422 {
423 switch (reg[REG_R0].type) {
424 default:
425 ERR("unknown register type\n");
426 ret = -EINVAL;
427 goto end;
428
429 case REG_STRING:
430 reg[REG_R0].v = (reg_strcmp(reg, "<") < 0);
431 break;
432 case REG_S64:
433 switch (reg[REG_R1].type) {
434 default:
435 ERR("unknown register type\n");
436 ret = -EINVAL;
437 goto end;
438
439 case REG_S64:
440 reg[REG_R0].v = (reg[REG_R0].v < reg[REG_R1].v);
441 break;
442 case REG_DOUBLE:
443 reg[REG_R0].v = (reg[REG_R0].v < reg[REG_R1].d);
444 break;
445 }
446 break;
447 case REG_DOUBLE:
448 switch (reg[REG_R1].type) {
449 default:
450 ERR("unknown register type\n");
451 ret = -EINVAL;
452 goto end;
453
454 case REG_S64:
455 reg[REG_R0].v = (reg[REG_R0].d < reg[REG_R1].v);
456 break;
457 case REG_DOUBLE:
458 reg[REG_R0].v = (reg[REG_R0].d < reg[REG_R1].d);
459 break;
460 }
461 break;
462 }
463 reg[REG_R0].type = REG_S64;
464 next_pc += sizeof(struct binary_op);
465 break;
466 }
467 case FILTER_OP_GE:
468 {
469 switch (reg[REG_R0].type) {
470 default:
471 ERR("unknown register type\n");
472 ret = -EINVAL;
473 goto end;
474
475 case REG_STRING:
476 reg[REG_R0].v = (reg_strcmp(reg, ">=") >= 0);
477 break;
478 case REG_S64:
479 switch (reg[REG_R1].type) {
480 default:
481 ERR("unknown register type\n");
482 ret = -EINVAL;
483 goto end;
484
485 case REG_S64:
486 reg[REG_R0].v = (reg[REG_R0].v >= reg[REG_R1].v);
487 break;
488 case REG_DOUBLE:
489 reg[REG_R0].v = (reg[REG_R0].v >= reg[REG_R1].d);
490 break;
491 }
492 break;
493 case REG_DOUBLE:
494 switch (reg[REG_R1].type) {
495 default:
496 ERR("unknown register type\n");
497 ret = -EINVAL;
498 goto end;
499
500 case REG_S64:
501 reg[REG_R0].v = (reg[REG_R0].d >= reg[REG_R1].v);
502 break;
503 case REG_DOUBLE:
504 reg[REG_R0].v = (reg[REG_R0].d >= reg[REG_R1].d);
505 break;
506 }
507 break;
508 }
509 reg[REG_R0].type = REG_S64;
510 next_pc += sizeof(struct binary_op);
511 break;
512 }
513 case FILTER_OP_LE:
514 {
515 switch (reg[REG_R0].type) {
516 default:
517 ERR("unknown register type\n");
518 ret = -EINVAL;
519 goto end;
520
521 case REG_STRING:
522 reg[REG_R0].v = (reg_strcmp(reg, "<=") <= 0);
523 break;
524 case REG_S64:
525 switch (reg[REG_R1].type) {
526 default:
527 ERR("unknown register type\n");
528 ret = -EINVAL;
529 goto end;
530
531 case REG_S64:
532 reg[REG_R0].v = (reg[REG_R0].v <= reg[REG_R1].v);
533 break;
534 case REG_DOUBLE:
535 reg[REG_R0].v = (reg[REG_R0].v <= reg[REG_R1].d);
536 break;
537 }
538 break;
539 case REG_DOUBLE:
540 switch (reg[REG_R1].type) {
541 default:
542 ERR("unknown register type\n");
543 ret = -EINVAL;
544 goto end;
545
546 case REG_S64:
547 reg[REG_R0].v = (reg[REG_R0].d <= reg[REG_R1].v);
548 break;
549 case REG_DOUBLE:
550 reg[REG_R0].v = (reg[REG_R0].d <= reg[REG_R1].d);
551 break;
552 }
553 break;
554 }
555 reg[REG_R0].type = REG_S64;
556 next_pc += sizeof(struct binary_op);
557 break;
558 }
559
560 /* unary */
561 case FILTER_OP_UNARY_PLUS:
562 {
563 next_pc += sizeof(struct unary_op);
564 break;
565 }
566 case FILTER_OP_UNARY_MINUS:
567 {
568 struct unary_op *insn = (struct unary_op *) pc;
569
570 switch (reg[insn->reg].type) {
571 default:
572 ERR("unknown register type\n");
573 ret = -EINVAL;
574 goto end;
575
576 case REG_STRING:
577 ERR("Unary minus can only be applied to numeric or floating point registers\n");
578 ret = -EINVAL;
579 goto end;
580 case REG_S64:
581 reg[insn->reg].v = -reg[insn->reg].v;
582 break;
583 case REG_DOUBLE:
584 reg[insn->reg].d = -reg[insn->reg].d;
585 break;
586 }
587 next_pc += sizeof(struct unary_op);
588 break;
589 }
590 case FILTER_OP_UNARY_NOT:
591 {
592 struct unary_op *insn = (struct unary_op *) pc;
593
594 switch (reg[insn->reg].type) {
595 default:
596 ERR("unknown register type\n");
597 ret = -EINVAL;
598 goto end;
599
600 case REG_STRING:
601 ERR("Unary not can only be applied to numeric or floating point registers\n");
602 ret = -EINVAL;
603 goto end;
604 case REG_S64:
605 reg[insn->reg].v = !reg[insn->reg].v;
606 break;
607 case REG_DOUBLE:
608 reg[insn->reg].d = !reg[insn->reg].d;
609 break;
610 }
611 reg[insn->reg].v = !reg[insn->reg].v;
612 next_pc += sizeof(struct unary_op);
613 break;
614 }
615 /* logical */
616 case FILTER_OP_AND:
617 {
618 struct logical_op *insn = (struct logical_op *) pc;
619
620 /* If REG_R0 is 0, skip and evaluate to 0 */
621 if ((reg[REG_R0].type == REG_S64 && reg[REG_R0].v == 0)
622 || (reg[REG_R0].type == REG_DOUBLE && reg[REG_R0].d == 0.0)) {
623 dbg_printf("Jumping to bytecode offset %u\n",
624 (unsigned int) insn->skip_offset);
625 next_pc = start_pc + insn->skip_offset;
626 } else {
627 next_pc += sizeof(struct logical_op);
628 }
629 break;
630 }
631 case FILTER_OP_OR:
632 {
633 struct logical_op *insn = (struct logical_op *) pc;
634
635 /* If REG_R0 is nonzero, skip and evaluate to 1 */
636
637 if ((reg[REG_R0].type == REG_S64 && reg[REG_R0].v != 0)
638 || (reg[REG_R0].type == REG_DOUBLE && reg[REG_R0].d != 0.0)) {
639 reg[REG_R0].v = 1;
640 dbg_printf("Jumping to bytecode offset %u\n",
641 (unsigned int) insn->skip_offset);
642 next_pc = start_pc + insn->skip_offset;
643 } else {
644 next_pc += sizeof(struct logical_op);
645 }
646 break;
647 }
648
649 /* load */
650 case FILTER_OP_LOAD_FIELD_REF:
651 {
652 struct load_op *insn = (struct load_op *) pc;
653 struct field_ref *ref = (struct field_ref *) insn->data;
654
655 dbg_printf("load field ref offset %u type %u\n",
656 ref->offset, ref->type);
657 switch (ref->type) {
658 case FIELD_REF_UNKNOWN:
659 default:
660 ERR("unknown field ref type\n");
661 ret = -EINVAL;
662 goto end;
663
664 case FIELD_REF_STRING:
665 reg[insn->reg].str =
666 *(const char * const *) &filter_stack_data[ref->offset];
667 reg[insn->reg].type = REG_STRING;
668 reg[insn->reg].seq_len = UINT_MAX;
669 reg[insn->reg].literal = 0;
670 dbg_printf("ref load string %s\n", reg[insn->reg].str);
671 break;
672 case FIELD_REF_SEQUENCE:
673 reg[insn->reg].seq_len =
674 *(unsigned long *) &filter_stack_data[ref->offset];
675 reg[insn->reg].str =
676 *(const char **) (&filter_stack_data[ref->offset
677 + sizeof(unsigned long)]);
678 reg[insn->reg].type = REG_STRING;
679 reg[insn->reg].literal = 0;
680 break;
681 case FIELD_REF_S64:
682 memcpy(&reg[insn->reg].v, &filter_stack_data[ref->offset],
683 sizeof(struct literal_numeric));
684 reg[insn->reg].type = REG_S64;
685 reg[insn->reg].literal = 0;
686 dbg_printf("ref load s64 %" PRIi64 "\n", reg[insn->reg].v);
687 break;
688 case FIELD_REF_DOUBLE:
689 memcpy(&reg[insn->reg].d, &filter_stack_data[ref->offset],
690 sizeof(struct literal_double));
691 reg[insn->reg].type = REG_DOUBLE;
692 reg[insn->reg].literal = 0;
693 dbg_printf("ref load double %g\n", reg[insn->reg].d);
694 break;
695 }
696
697 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
698 break;
699 }
700
701 case FILTER_OP_LOAD_STRING:
702 {
703 struct load_op *insn = (struct load_op *) pc;
704
705 dbg_printf("load string %s\n", insn->data);
706 reg[insn->reg].str = insn->data;
707 reg[insn->reg].type = REG_STRING;
708 reg[insn->reg].seq_len = UINT_MAX;
709 reg[insn->reg].literal = 1;
710 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
711 break;
712 }
713
714 case FILTER_OP_LOAD_S64:
715 {
716 struct load_op *insn = (struct load_op *) pc;
717
718 memcpy(&reg[insn->reg].v, insn->data,
719 sizeof(struct literal_numeric));
720 dbg_printf("load s64 %" PRIi64 "\n", reg[insn->reg].v);
721 reg[insn->reg].type = REG_S64;
722 next_pc += sizeof(struct load_op)
723 + sizeof(struct literal_numeric);
724 break;
725 }
726
727 case FILTER_OP_LOAD_DOUBLE:
728 {
729 struct load_op *insn = (struct load_op *) pc;
730
731 memcpy(&reg[insn->reg].d, insn->data,
732 sizeof(struct literal_double));
733 dbg_printf("load s64 %g\n", reg[insn->reg].d);
734 reg[insn->reg].type = REG_DOUBLE;
735 next_pc += sizeof(struct load_op)
736 + sizeof(struct literal_double);
737 break;
738 }
739 }
740 }
741 end:
742 /* return 0 (discard) on error */
743 if (ret)
744 return 0;
745 return retval;
746 }
747
748 static
749 int bin_op_compare_check(struct vreg reg[NR_REG], const char *str)
750 {
751 switch (reg[REG_R0].type) {
752 default:
753 goto error_unknown;
754
755 case REG_STRING:
756 switch (reg[REG_R1].type) {
757 default:
758 goto error_unknown;
759
760 case REG_STRING:
761 break;
762 case REG_S64:
763 case REG_DOUBLE:
764 goto error_mismatch;
765 }
766 break;
767 case REG_S64:
768 case REG_DOUBLE:
769 switch (reg[REG_R1].type) {
770 default:
771 goto error_unknown;
772
773 case REG_STRING:
774 goto error_mismatch;
775
776 case REG_S64:
777 case REG_DOUBLE:
778 break;
779 }
780 break;
781 }
782 return 0;
783
784 error_unknown:
785
786 return -EINVAL;
787 error_mismatch:
788 ERR("type mismatch for '%s' binary operator\n", str);
789 return -EINVAL;
790 }
791
792 static
793 int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode)
794 {
795 void *pc, *next_pc, *start_pc;
796 int ret = -EINVAL;
797 struct vreg reg[NR_REG];
798 int i;
799
800 for (i = 0; i < NR_REG; i++) {
801 reg[i].type = REG_S64;
802 reg[i].literal = 0;
803 }
804
805 start_pc = &bytecode->data[0];
806 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
807 pc = next_pc) {
808 if (unlikely(pc >= start_pc + bytecode->len)) {
809 ERR("filter bytecode overflow\n");
810 ret = -EINVAL;
811 goto end;
812 }
813 dbg_printf("Validating op %s (%u)\n",
814 print_op((unsigned int) *(filter_opcode_t *) pc),
815 (unsigned int) *(filter_opcode_t *) pc);
816 switch (*(filter_opcode_t *) pc) {
817 case FILTER_OP_UNKNOWN:
818 default:
819 ERR("unknown bytecode op %u\n",
820 (unsigned int) *(filter_opcode_t *) pc);
821 ret = -EINVAL;
822 goto end;
823
824 case FILTER_OP_RETURN:
825 ret = 0;
826 goto end;
827
828 /* binary */
829 case FILTER_OP_MUL:
830 case FILTER_OP_DIV:
831 case FILTER_OP_MOD:
832 case FILTER_OP_PLUS:
833 case FILTER_OP_MINUS:
834 case FILTER_OP_RSHIFT:
835 case FILTER_OP_LSHIFT:
836 case FILTER_OP_BIN_AND:
837 case FILTER_OP_BIN_OR:
838 case FILTER_OP_BIN_XOR:
839 ERR("unsupported bytecode op %u\n",
840 (unsigned int) *(filter_opcode_t *) pc);
841 ret = -EINVAL;
842 goto end;
843
844 case FILTER_OP_EQ:
845 {
846 ret = bin_op_compare_check(reg, "==");
847 if (ret)
848 goto end;
849 reg[REG_R0].type = REG_S64;
850 next_pc += sizeof(struct binary_op);
851 break;
852 }
853 case FILTER_OP_NE:
854 {
855 ret = bin_op_compare_check(reg, "!=");
856 if (ret)
857 goto end;
858 reg[REG_R0].type = REG_S64;
859 next_pc += sizeof(struct binary_op);
860 break;
861 }
862 case FILTER_OP_GT:
863 {
864 ret = bin_op_compare_check(reg, ">");
865 if (ret)
866 goto end;
867 reg[REG_R0].type = REG_S64;
868 next_pc += sizeof(struct binary_op);
869 break;
870 }
871 case FILTER_OP_LT:
872 {
873 ret = bin_op_compare_check(reg, "<");
874 if (ret)
875 goto end;
876 reg[REG_R0].type = REG_S64;
877 next_pc += sizeof(struct binary_op);
878 break;
879 }
880 case FILTER_OP_GE:
881 {
882 ret = bin_op_compare_check(reg, ">=");
883 if (ret)
884 goto end;
885 reg[REG_R0].type = REG_S64;
886 next_pc += sizeof(struct binary_op);
887 break;
888 }
889 case FILTER_OP_LE:
890 {
891 ret = bin_op_compare_check(reg, "<=");
892 if (ret)
893 goto end;
894 reg[REG_R0].type = REG_S64;
895 next_pc += sizeof(struct binary_op);
896 break;
897 }
898
899 /* unary */
900 case FILTER_OP_UNARY_PLUS:
901 case FILTER_OP_UNARY_MINUS:
902 case FILTER_OP_UNARY_NOT:
903 {
904 struct unary_op *insn = (struct unary_op *) pc;
905
906 if (unlikely(insn->reg >= REG_ERROR)) {
907 ERR("invalid register %u\n",
908 (unsigned int) insn->reg);
909 ret = -EINVAL;
910 goto end;
911 }
912 switch (reg[insn->reg].type) {
913 default:
914 ERR("unknown register type\n");
915 ret = -EINVAL;
916 goto end;
917
918 case REG_STRING:
919 ERR("Unary op can only be applied to numeric or floating point registers\n");
920 ret = -EINVAL;
921 goto end;
922 case REG_S64:
923 break;
924 case REG_DOUBLE:
925 break;
926 }
927 next_pc += sizeof(struct unary_op);
928 break;
929 }
930 /* logical */
931 case FILTER_OP_AND:
932 case FILTER_OP_OR:
933 {
934 struct logical_op *insn = (struct logical_op *) pc;
935
936 if (unlikely(reg[REG_R0].type == REG_STRING)) {
937 ERR("Logical operator 'and' can only be applied to numeric and floating point registers\n");
938 ret = -EINVAL;
939 goto end;
940 }
941
942 dbg_printf("Validate jumping to bytecode offset %u\n",
943 (unsigned int) insn->skip_offset);
944 if (unlikely(start_pc + insn->skip_offset <= pc)) {
945 ERR("Loops are not allowed in bytecode\n");
946 ret = -EINVAL;
947 goto end;
948 }
949 next_pc += sizeof(struct logical_op);
950 break;
951 }
952
953 /* load */
954 case FILTER_OP_LOAD_FIELD_REF:
955 {
956 struct load_op *insn = (struct load_op *) pc;
957 struct field_ref *ref = (struct field_ref *) insn->data;
958
959 if (unlikely(insn->reg >= REG_ERROR)) {
960 ERR("invalid register %u\n",
961 (unsigned int) insn->reg);
962 ret = -EINVAL;
963 goto end;
964 }
965 dbg_printf("Validate load field ref offset %u type %u\n",
966 ref->offset, ref->type);
967 switch (ref->type) {
968 case FIELD_REF_UNKNOWN:
969 default:
970 ERR("unknown field ref type\n");
971 ret = -EINVAL;
972 goto end;
973
974 case FIELD_REF_STRING:
975 reg[insn->reg].type = REG_STRING;
976 reg[insn->reg].literal = 0;
977 break;
978 case FIELD_REF_SEQUENCE:
979 reg[insn->reg].type = REG_STRING;
980 reg[insn->reg].literal = 0;
981 break;
982 case FIELD_REF_S64:
983 reg[insn->reg].type = REG_S64;
984 reg[insn->reg].literal = 0;
985 break;
986 case FIELD_REF_DOUBLE:
987 reg[insn->reg].type = REG_DOUBLE;
988 reg[insn->reg].literal = 0;
989 break;
990 }
991
992 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
993 break;
994 }
995
996 case FILTER_OP_LOAD_STRING:
997 {
998 struct load_op *insn = (struct load_op *) pc;
999
1000 if (unlikely(insn->reg >= REG_ERROR)) {
1001 ERR("invalid register %u\n",
1002 (unsigned int) insn->reg);
1003 ret = -EINVAL;
1004 goto end;
1005 }
1006 reg[insn->reg].type = REG_STRING;
1007 reg[insn->reg].literal = 1;
1008 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1009 break;
1010 }
1011
1012 case FILTER_OP_LOAD_S64:
1013 {
1014 struct load_op *insn = (struct load_op *) pc;
1015
1016 if (unlikely(insn->reg >= REG_ERROR)) {
1017 ERR("invalid register %u\n",
1018 (unsigned int) insn->reg);
1019 ret = -EINVAL;
1020 goto end;
1021 }
1022 reg[insn->reg].type = REG_S64;
1023 next_pc += sizeof(struct load_op)
1024 + sizeof(struct literal_numeric);
1025 break;
1026 }
1027
1028 case FILTER_OP_LOAD_DOUBLE:
1029 {
1030 struct load_op *insn = (struct load_op *) pc;
1031
1032 if (unlikely(insn->reg >= REG_ERROR)) {
1033 ERR("invalid register %u\n",
1034 (unsigned int) insn->reg);
1035 ret = -EINVAL;
1036 goto end;
1037 }
1038 reg[insn->reg].type = REG_DOUBLE;
1039 next_pc += sizeof(struct load_op)
1040 + sizeof(struct literal_double);
1041 break;
1042 }
1043 }
1044 }
1045 end:
1046 return ret;
1047 }
1048
1049 static
1050 int apply_field_reloc(struct ltt_event *event,
1051 struct bytecode_runtime *runtime,
1052 uint32_t runtime_len,
1053 uint32_t reloc_offset,
1054 const char *field_name)
1055 {
1056 const struct lttng_event_desc *desc;
1057 const struct lttng_event_field *fields, *field = NULL;
1058 unsigned int nr_fields, i;
1059 struct field_ref *field_ref;
1060 uint32_t field_offset = 0;
1061
1062 dbg_printf("Apply reloc: %u %s\n", reloc_offset, field_name);
1063
1064 /* Ensure that the reloc is within the code */
1065 if (runtime_len - reloc_offset < sizeof(uint16_t))
1066 return -EINVAL;
1067
1068 /* Lookup event by name */
1069 desc = event->desc;
1070 if (!desc)
1071 return -EINVAL;
1072 fields = desc->fields;
1073 if (!fields)
1074 return -EINVAL;
1075 nr_fields = desc->nr_fields;
1076 for (i = 0; i < nr_fields; i++) {
1077 if (!strcmp(fields[i].name, field_name)) {
1078 field = &fields[i];
1079 break;
1080 }
1081 /* compute field offset */
1082 switch (fields[i].type.atype) {
1083 case atype_integer:
1084 case atype_enum:
1085 field_offset += sizeof(int64_t);
1086 break;
1087 case atype_array:
1088 case atype_sequence:
1089 field_offset += sizeof(unsigned long);
1090 field_offset += sizeof(void *);
1091 break;
1092 case atype_string:
1093 field_offset += sizeof(void *);
1094 break;
1095 case atype_float:
1096 field_offset += sizeof(double);
1097 break;
1098 default:
1099 return -EINVAL;
1100 }
1101 }
1102 if (!field)
1103 return -EINVAL;
1104
1105 /* Check if field offset is too large for 16-bit offset */
1106 if (field_offset > FILTER_BYTECODE_MAX_LEN)
1107 return -EINVAL;
1108
1109 /* set type */
1110 field_ref = (struct field_ref *) &runtime->data[reloc_offset];
1111 switch (field->type.atype) {
1112 case atype_integer:
1113 case atype_enum:
1114 field_ref->type = FIELD_REF_S64;
1115 field_ref->type = FIELD_REF_S64;
1116 break;
1117 case atype_array:
1118 case atype_sequence:
1119 field_ref->type = FIELD_REF_SEQUENCE;
1120 break;
1121 case atype_string:
1122 field_ref->type = FIELD_REF_STRING;
1123 break;
1124 case atype_float:
1125 field_ref->type = FIELD_REF_DOUBLE;
1126 break;
1127 default:
1128 return -EINVAL;
1129 }
1130 /* set offset */
1131 field_ref->offset = (uint16_t) field_offset;
1132 return 0;
1133 }
1134
1135 /*
1136 * Take a bytecode with reloc table and link it to an event to create a
1137 * bytecode runtime.
1138 */
1139 static
1140 int _lttng_filter_event_link_bytecode(struct ltt_event *event,
1141 struct lttng_ust_filter_bytecode *filter_bytecode)
1142 {
1143 int ret, offset, next_offset;
1144 struct bytecode_runtime *runtime = NULL;
1145 size_t runtime_alloc_len;
1146
1147 if (!filter_bytecode)
1148 return 0;
1149 /* Even is not connected to any description */
1150 if (!event->desc)
1151 return 0;
1152 /* Bytecode already linked */
1153 if (event->filter || event->filter_data)
1154 return 0;
1155
1156 dbg_printf("Linking\n");
1157
1158 /* We don't need the reloc table in the runtime */
1159 runtime_alloc_len = sizeof(*runtime) + filter_bytecode->reloc_offset;
1160 runtime = zmalloc(runtime_alloc_len);
1161 if (!runtime) {
1162 ret = -ENOMEM;
1163 goto link_error;
1164 }
1165 runtime->len = filter_bytecode->reloc_offset;
1166 /* copy original bytecode */
1167 memcpy(runtime->data, filter_bytecode->data, runtime->len);
1168 /*
1169 * apply relocs. Those are a uint16_t (offset in bytecode)
1170 * followed by a string (field name).
1171 */
1172 for (offset = filter_bytecode->reloc_offset;
1173 offset < filter_bytecode->len;
1174 offset = next_offset) {
1175 uint16_t reloc_offset =
1176 *(uint16_t *) &filter_bytecode->data[offset];
1177 const char *field_name =
1178 (const char *) &filter_bytecode->data[offset + sizeof(uint16_t)];
1179
1180 ret = apply_field_reloc(event, runtime, runtime->len, reloc_offset, field_name);
1181 if (ret) {
1182 goto link_error;
1183 }
1184 next_offset = offset + sizeof(uint16_t) + strlen(field_name) + 1;
1185 }
1186 /* Validate bytecode */
1187 ret = lttng_filter_validate_bytecode(runtime);
1188 if (ret) {
1189 goto link_error;
1190 }
1191 event->filter_data = runtime;
1192 event->filter = lttng_filter_interpret_bytecode;
1193 return 0;
1194
1195 link_error:
1196 event->filter = lttng_filter_false;
1197 free(runtime);
1198 return ret;
1199 }
1200
1201 void lttng_filter_event_link_bytecode(struct ltt_event *event,
1202 struct lttng_ust_filter_bytecode *filter_bytecode)
1203 {
1204 int ret;
1205
1206 ret = _lttng_filter_event_link_bytecode(event, filter_bytecode);
1207 if (ret) {
1208 fprintf(stderr, "[lttng filter] error linking event bytecode\n");
1209 }
1210 }
1211
1212 /*
1213 * Link bytecode to all events for a wildcard. Skips events that already
1214 * have a bytecode linked.
1215 * We do not set each event's filter_bytecode field, because they do not
1216 * own the filter_bytecode: the wildcard owns it.
1217 */
1218 void lttng_filter_wildcard_link_bytecode(struct session_wildcard *wildcard)
1219 {
1220 struct ltt_event *event;
1221 int ret;
1222
1223 if (!wildcard->filter_bytecode)
1224 return;
1225
1226 cds_list_for_each_entry(event, &wildcard->events, wildcard_list) {
1227 if (event->filter)
1228 continue;
1229 ret = _lttng_filter_event_link_bytecode(event,
1230 wildcard->filter_bytecode);
1231 if (ret) {
1232 fprintf(stderr, "[lttng filter] error linking wildcard bytecode\n");
1233 }
1234
1235 }
1236 return;
1237 }
1238
1239 /*
1240 * Need to attach filter to an event before starting tracing for the
1241 * session. We own the filter_bytecode if we return success.
1242 */
1243 int lttng_filter_event_attach_bytecode(struct ltt_event *event,
1244 struct lttng_ust_filter_bytecode *filter_bytecode)
1245 {
1246 if (event->chan->session->been_active)
1247 return -EPERM;
1248 if (event->filter_bytecode)
1249 return -EEXIST;
1250 event->filter_bytecode = filter_bytecode;
1251 return 0;
1252 }
1253
1254 /*
1255 * Need to attach filter to a wildcard before starting tracing for the
1256 * session. We own the filter_bytecode if we return success.
1257 */
1258 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard *wildcard,
1259 struct lttng_ust_filter_bytecode *filter_bytecode)
1260 {
1261 if (wildcard->chan->session->been_active)
1262 return -EPERM;
1263 if (wildcard->filter_bytecode)
1264 return -EEXIST;
1265 wildcard->filter_bytecode = filter_bytecode;
1266 return 0;
1267 }
This page took 0.055684 seconds and 5 git commands to generate.