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