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