4 * LTTng UST filter code.
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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.
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.
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
26 #include <lttng/ust-events.h>
32 #include <usterr-signal-safe.h>
33 #include "filter-bytecode.h"
38 #define min_t(type, a, b) \
39 ((type) (a) < (type) (b) ? (type) (a) : (type) (b))
43 #define likely(x) __builtin_expect(!!(x), 1)
47 #define unlikely(x) __builtin_expect(!!(x), 0)
51 #define dbg_printf(fmt, args...) printf("[debug bytecode] " fmt, ## args)
53 #define dbg_printf(fmt, args...) \
55 /* do nothing but check printf format */ \
57 printf("[debug bytecode] " fmt, ## args); \
62 struct bytecode_runtime
{
74 /* Validation registers */
77 int literal
; /* is string literal ? */
80 /* Execution registers */
88 int literal
; /* is string literal ? */
91 static const char *opnames
[] = {
92 [ FILTER_OP_UNKNOWN
] = "UNKNOWN",
94 [ FILTER_OP_RETURN
] = "RETURN",
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",
108 /* binary comparators */
109 [ FILTER_OP_EQ
] = "EQ",
110 [ FILTER_OP_NE
] = "NE",
111 [ FILTER_OP_GT
] = "GT",
112 [ FILTER_OP_LT
] = "LT",
113 [ FILTER_OP_GE
] = "GE",
114 [ FILTER_OP_LE
] = "LE",
116 /* string binary comparators */
117 [ FILTER_OP_EQ_STRING
] = "EQ_STRING",
118 [ FILTER_OP_NE_STRING
] = "NE_STRING",
119 [ FILTER_OP_GT_STRING
] = "GT_STRING",
120 [ FILTER_OP_LT_STRING
] = "LT_STRING",
121 [ FILTER_OP_GE_STRING
] = "GE_STRING",
122 [ FILTER_OP_LE_STRING
] = "LE_STRING",
124 /* s64 binary comparators */
125 [ FILTER_OP_EQ_S64
] = "EQ_S64",
126 [ FILTER_OP_NE_S64
] = "NE_S64",
127 [ FILTER_OP_GT_S64
] = "GT_S64",
128 [ FILTER_OP_LT_S64
] = "LT_S64",
129 [ FILTER_OP_GE_S64
] = "GE_S64",
130 [ FILTER_OP_LE_S64
] = "LE_S64",
132 /* double binary comparators */
133 [ FILTER_OP_EQ_DOUBLE
] = "EQ_DOUBLE",
134 [ FILTER_OP_NE_DOUBLE
] = "NE_DOUBLE",
135 [ FILTER_OP_GT_DOUBLE
] = "GT_DOUBLE",
136 [ FILTER_OP_LT_DOUBLE
] = "LT_DOUBLE",
137 [ FILTER_OP_GE_DOUBLE
] = "GE_DOUBLE",
138 [ FILTER_OP_LE_DOUBLE
] = "LE_DOUBLE",
142 [ FILTER_OP_UNARY_PLUS
] = "UNARY_PLUS",
143 [ FILTER_OP_UNARY_MINUS
] = "UNARY_MINUS",
144 [ FILTER_OP_UNARY_NOT
] = "UNARY_NOT",
145 [ FILTER_OP_UNARY_PLUS_S64
] = "UNARY_PLUS_S64",
146 [ FILTER_OP_UNARY_MINUS_S64
] = "UNARY_MINUS_S64",
147 [ FILTER_OP_UNARY_NOT_S64
] = "UNARY_NOT_S64",
148 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = "UNARY_PLUS_DOUBLE",
149 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = "UNARY_MINUS_DOUBLE",
150 [ FILTER_OP_UNARY_NOT_DOUBLE
] = "UNARY_NOT_DOUBLE",
153 [ FILTER_OP_AND
] = "AND",
154 [ FILTER_OP_OR
] = "OR",
155 [ FILTER_OP_AND_S64
] = "AND_S64",
156 [ FILTER_OP_OR_S64
] = "OR_S64",
157 [ FILTER_OP_AND_DOUBLE
] = "AND_DOUBLE",
158 [ FILTER_OP_OR_DOUBLE
] = "OR_DOUBLE",
161 [ FILTER_OP_LOAD_FIELD_REF
] = "LOAD_FIELD_REF",
162 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = "LOAD_FIELD_REF_STRING",
163 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = "LOAD_FIELD_REF_SEQUENCE",
164 [ FILTER_OP_LOAD_FIELD_REF_S64
] = "LOAD_FIELD_REF_S64",
165 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = "LOAD_FIELD_REF_DOUBLE",
167 [ FILTER_OP_LOAD_STRING
] = "LOAD_STRING",
168 [ FILTER_OP_LOAD_S64
] = "LOAD_S64",
169 [ FILTER_OP_LOAD_DOUBLE
] = "LOAD_DOUBLE",
173 const char *print_op(enum filter_op op
)
175 if (op
>= NR_FILTER_OPS
)
182 * -1: wildcard found.
183 * -2: unknown escape char.
188 int parse_char(const char **p
)
208 int reg_strcmp(struct reg reg
[NR_REG
], const char *cmp_type
)
210 const char *p
= reg
[REG_R0
].str
, *q
= reg
[REG_R1
].str
;
217 if (unlikely(p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')) {
218 if (q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')
224 if (unlikely(q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')) {
225 if (p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')
231 if (reg
[REG_R0
].literal
) {
232 ret
= parse_char(&p
);
235 } else if (ret
== -2) {
238 /* else compare both char */
240 if (reg
[REG_R1
].literal
) {
241 ret
= parse_char(&q
);
244 } else if (ret
== -2) {
265 int lttng_filter_false(void *filter_data
,
266 const char *filter_stack_data
)
271 #ifdef INTERPRETER_USE_SWITCH
274 * Fallback for compilers that do not support taking address of labels.
278 start_pc = &bytecode->data[0]; \
279 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
281 dbg_printf("Executing op %s (%u)\n", \
282 print_op((unsigned int) *(filter_opcode_t *) pc), \
283 (unsigned int) *(filter_opcode_t *) pc); \
284 switch (*(filter_opcode_t *) pc) {
286 #define OP(name) case name
296 * Dispatch-table based interpreter.
300 start_pc = &bytecode->data[0]; \
301 pc = next_pc = start_pc; \
302 if (unlikely(pc - start_pc >= bytecode->len)) \
304 goto *dispatch[*(filter_opcode_t *) pc];
311 goto *dispatch[*(filter_opcode_t *) pc];
318 int lttng_filter_interpret_bytecode(void *filter_data
,
319 const char *filter_stack_data
)
321 struct bytecode_runtime
*bytecode
= filter_data
;
322 void *pc
, *next_pc
, *start_pc
;
325 struct reg reg
[NR_REG
];
326 #ifndef INTERPRETER_USE_SWITCH
327 static void *dispatch
[NR_FILTER_OPS
] = {
328 [ FILTER_OP_UNKNOWN
] = &&LABEL_FILTER_OP_UNKNOWN
,
330 [ FILTER_OP_RETURN
] = &&LABEL_FILTER_OP_RETURN
,
333 [ FILTER_OP_MUL
] = &&LABEL_FILTER_OP_MUL
,
334 [ FILTER_OP_DIV
] = &&LABEL_FILTER_OP_DIV
,
335 [ FILTER_OP_MOD
] = &&LABEL_FILTER_OP_MOD
,
336 [ FILTER_OP_PLUS
] = &&LABEL_FILTER_OP_PLUS
,
337 [ FILTER_OP_MINUS
] = &&LABEL_FILTER_OP_MINUS
,
338 [ FILTER_OP_RSHIFT
] = &&LABEL_FILTER_OP_RSHIFT
,
339 [ FILTER_OP_LSHIFT
] = &&LABEL_FILTER_OP_LSHIFT
,
340 [ FILTER_OP_BIN_AND
] = &&LABEL_FILTER_OP_BIN_AND
,
341 [ FILTER_OP_BIN_OR
] = &&LABEL_FILTER_OP_BIN_OR
,
342 [ FILTER_OP_BIN_XOR
] = &&LABEL_FILTER_OP_BIN_XOR
,
344 /* binary comparators */
345 [ FILTER_OP_EQ
] = &&LABEL_FILTER_OP_EQ
,
346 [ FILTER_OP_NE
] = &&LABEL_FILTER_OP_NE
,
347 [ FILTER_OP_GT
] = &&LABEL_FILTER_OP_GT
,
348 [ FILTER_OP_LT
] = &&LABEL_FILTER_OP_LT
,
349 [ FILTER_OP_GE
] = &&LABEL_FILTER_OP_GE
,
350 [ FILTER_OP_LE
] = &&LABEL_FILTER_OP_LE
,
352 /* string binary comparator */
353 [ FILTER_OP_EQ_STRING
] = &&LABEL_FILTER_OP_EQ_STRING
,
354 [ FILTER_OP_NE_STRING
] = &&LABEL_FILTER_OP_NE_STRING
,
355 [ FILTER_OP_GT_STRING
] = &&LABEL_FILTER_OP_GT_STRING
,
356 [ FILTER_OP_LT_STRING
] = &&LABEL_FILTER_OP_LT_STRING
,
357 [ FILTER_OP_GE_STRING
] = &&LABEL_FILTER_OP_GE_STRING
,
358 [ FILTER_OP_LE_STRING
] = &&LABEL_FILTER_OP_LE_STRING
,
360 /* s64 binary comparator */
361 [ FILTER_OP_EQ_S64
] = &&LABEL_FILTER_OP_EQ_S64
,
362 [ FILTER_OP_NE_S64
] = &&LABEL_FILTER_OP_NE_S64
,
363 [ FILTER_OP_GT_S64
] = &&LABEL_FILTER_OP_GT_S64
,
364 [ FILTER_OP_LT_S64
] = &&LABEL_FILTER_OP_LT_S64
,
365 [ FILTER_OP_GE_S64
] = &&LABEL_FILTER_OP_GE_S64
,
366 [ FILTER_OP_LE_S64
] = &&LABEL_FILTER_OP_LE_S64
,
368 /* double binary comparator */
369 [ FILTER_OP_EQ_DOUBLE
] = &&LABEL_FILTER_OP_EQ_DOUBLE
,
370 [ FILTER_OP_NE_DOUBLE
] = &&LABEL_FILTER_OP_NE_DOUBLE
,
371 [ FILTER_OP_GT_DOUBLE
] = &&LABEL_FILTER_OP_GT_DOUBLE
,
372 [ FILTER_OP_LT_DOUBLE
] = &&LABEL_FILTER_OP_LT_DOUBLE
,
373 [ FILTER_OP_GE_DOUBLE
] = &&LABEL_FILTER_OP_GE_DOUBLE
,
374 [ FILTER_OP_LE_DOUBLE
] = &&LABEL_FILTER_OP_LE_DOUBLE
,
377 [ FILTER_OP_UNARY_PLUS
] = &&LABEL_FILTER_OP_UNARY_PLUS
,
378 [ FILTER_OP_UNARY_MINUS
] = &&LABEL_FILTER_OP_UNARY_MINUS
,
379 [ FILTER_OP_UNARY_NOT
] = &&LABEL_FILTER_OP_UNARY_NOT
,
380 [ FILTER_OP_UNARY_PLUS_S64
] = &&LABEL_FILTER_OP_UNARY_PLUS_S64
,
381 [ FILTER_OP_UNARY_MINUS_S64
] = &&LABEL_FILTER_OP_UNARY_MINUS_S64
,
382 [ FILTER_OP_UNARY_NOT_S64
] = &&LABEL_FILTER_OP_UNARY_NOT_S64
,
383 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE
,
384 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE
,
385 [ FILTER_OP_UNARY_NOT_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE
,
388 [ FILTER_OP_AND
] = &&LABEL_FILTER_OP_AND
,
389 [ FILTER_OP_OR
] = &&LABEL_FILTER_OP_OR
,
390 [ FILTER_OP_AND_S64
] = &&LABEL_FILTER_OP_AND_S64
,
391 [ FILTER_OP_OR_S64
] = &&LABEL_FILTER_OP_OR_S64
,
392 [ FILTER_OP_AND_DOUBLE
] = &&LABEL_FILTER_OP_AND_DOUBLE
,
393 [ FILTER_OP_OR_DOUBLE
] = &&LABEL_FILTER_OP_OR_DOUBLE
,
396 [ FILTER_OP_LOAD_FIELD_REF
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF
,
397 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING
,
398 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE
,
399 [ FILTER_OP_LOAD_FIELD_REF_S64
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64
,
400 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE
,
402 [ FILTER_OP_LOAD_STRING
] = &&LABEL_FILTER_OP_LOAD_STRING
,
403 [ FILTER_OP_LOAD_S64
] = &&LABEL_FILTER_OP_LOAD_S64
,
404 [ FILTER_OP_LOAD_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_DOUBLE
,
406 #endif /* #ifndef INTERPRETER_USE_SWITCH */
410 OP(FILTER_OP_UNKNOWN
):
411 OP(FILTER_OP_LOAD_FIELD_REF
):
412 #ifdef INTERPRETER_USE_SWITCH
414 #endif /* INTERPRETER_USE_SWITCH */
415 ERR("unknown bytecode op %u\n",
416 (unsigned int) *(filter_opcode_t
*) pc
);
420 OP(FILTER_OP_RETURN
):
431 OP(FILTER_OP_RSHIFT
):
432 OP(FILTER_OP_LSHIFT
):
433 OP(FILTER_OP_BIN_AND
):
434 OP(FILTER_OP_BIN_OR
):
435 OP(FILTER_OP_BIN_XOR
):
436 ERR("unsupported bytecode op %u\n",
437 (unsigned int) *(filter_opcode_t
*) pc
);
447 ERR("unsupported non-specialized bytecode op %u\n",
448 (unsigned int) *(filter_opcode_t
*) pc
);
452 OP(FILTER_OP_EQ_STRING
):
454 reg
[REG_R0
].v
= (reg_strcmp(reg
, "==") == 0);
455 reg
[REG_R0
].type
= REG_S64
;
456 next_pc
+= sizeof(struct binary_op
);
459 OP(FILTER_OP_NE_STRING
):
461 reg
[REG_R0
].v
= (reg_strcmp(reg
, "!=") != 0);
462 reg
[REG_R0
].type
= REG_S64
;
463 next_pc
+= sizeof(struct binary_op
);
466 OP(FILTER_OP_GT_STRING
):
468 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">") > 0);
469 reg
[REG_R0
].type
= REG_S64
;
470 next_pc
+= sizeof(struct binary_op
);
473 OP(FILTER_OP_LT_STRING
):
475 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<") < 0);
476 reg
[REG_R0
].type
= REG_S64
;
477 next_pc
+= sizeof(struct binary_op
);
480 OP(FILTER_OP_GE_STRING
):
482 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">=") >= 0);
483 reg
[REG_R0
].type
= REG_S64
;
484 next_pc
+= sizeof(struct binary_op
);
487 OP(FILTER_OP_LE_STRING
):
489 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<=") <= 0);
490 reg
[REG_R0
].type
= REG_S64
;
491 next_pc
+= sizeof(struct binary_op
);
495 OP(FILTER_OP_EQ_S64
):
497 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].v
);
498 reg
[REG_R0
].type
= REG_S64
;
499 next_pc
+= sizeof(struct binary_op
);
502 OP(FILTER_OP_NE_S64
):
504 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].v
);
505 reg
[REG_R0
].type
= REG_S64
;
506 next_pc
+= sizeof(struct binary_op
);
509 OP(FILTER_OP_GT_S64
):
511 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].v
);
512 reg
[REG_R0
].type
= REG_S64
;
513 next_pc
+= sizeof(struct binary_op
);
516 OP(FILTER_OP_LT_S64
):
518 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].v
);
519 reg
[REG_R0
].type
= REG_S64
;
520 next_pc
+= sizeof(struct binary_op
);
523 OP(FILTER_OP_GE_S64
):
525 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].v
);
526 reg
[REG_R0
].type
= REG_S64
;
527 next_pc
+= sizeof(struct binary_op
);
530 OP(FILTER_OP_LE_S64
):
532 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].v
);
533 reg
[REG_R0
].type
= REG_S64
;
534 next_pc
+= sizeof(struct binary_op
);
538 OP(FILTER_OP_EQ_DOUBLE
):
540 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
541 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
542 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
543 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
544 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].d
);
545 reg
[REG_R0
].type
= REG_S64
;
546 next_pc
+= sizeof(struct binary_op
);
549 OP(FILTER_OP_NE_DOUBLE
):
551 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
552 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
553 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
554 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
555 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].d
);
556 reg
[REG_R0
].type
= REG_S64
;
557 next_pc
+= sizeof(struct binary_op
);
560 OP(FILTER_OP_GT_DOUBLE
):
562 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
563 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
564 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
565 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
566 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].d
);
567 reg
[REG_R0
].type
= REG_S64
;
568 next_pc
+= sizeof(struct binary_op
);
571 OP(FILTER_OP_LT_DOUBLE
):
573 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
574 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
575 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
576 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
577 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].d
);
578 reg
[REG_R0
].type
= REG_S64
;
579 next_pc
+= sizeof(struct binary_op
);
582 OP(FILTER_OP_GE_DOUBLE
):
584 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
585 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
586 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
587 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
588 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].d
);
589 reg
[REG_R0
].type
= REG_S64
;
590 next_pc
+= sizeof(struct binary_op
);
593 OP(FILTER_OP_LE_DOUBLE
):
595 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
596 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
597 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
598 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
599 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].d
);
600 reg
[REG_R0
].type
= REG_S64
;
601 next_pc
+= sizeof(struct binary_op
);
606 OP(FILTER_OP_UNARY_PLUS
):
607 OP(FILTER_OP_UNARY_MINUS
):
608 OP(FILTER_OP_UNARY_NOT
):
609 ERR("unsupported non-specialized bytecode op %u\n",
610 (unsigned int) *(filter_opcode_t
*) pc
);
615 OP(FILTER_OP_UNARY_PLUS_S64
):
616 OP(FILTER_OP_UNARY_PLUS_DOUBLE
):
618 next_pc
+= sizeof(struct unary_op
);
621 OP(FILTER_OP_UNARY_MINUS_S64
):
623 struct unary_op
*insn
= (struct unary_op
*) pc
;
625 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
626 next_pc
+= sizeof(struct unary_op
);
629 OP(FILTER_OP_UNARY_MINUS_DOUBLE
):
631 struct unary_op
*insn
= (struct unary_op
*) pc
;
633 reg
[insn
->reg
].d
= -reg
[insn
->reg
].d
;
634 next_pc
+= sizeof(struct unary_op
);
637 OP(FILTER_OP_UNARY_NOT_S64
):
639 struct unary_op
*insn
= (struct unary_op
*) pc
;
641 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
642 next_pc
+= sizeof(struct unary_op
);
645 OP(FILTER_OP_UNARY_NOT_DOUBLE
):
647 struct unary_op
*insn
= (struct unary_op
*) pc
;
649 reg
[insn
->reg
].d
= !reg
[insn
->reg
].d
;
650 next_pc
+= sizeof(struct unary_op
);
657 ERR("unsupported non-specialized bytecode op %u\n",
658 (unsigned int) *(filter_opcode_t
*) pc
);
662 OP(FILTER_OP_AND_S64
):
664 struct logical_op
*insn
= (struct logical_op
*) pc
;
666 /* If REG_R0 is 0, skip and evaluate to 0 */
667 if (unlikely(reg
[REG_R0
].v
== 0)) {
668 dbg_printf("Jumping to bytecode offset %u\n",
669 (unsigned int) insn
->skip_offset
);
670 next_pc
= start_pc
+ insn
->skip_offset
;
672 next_pc
+= sizeof(struct logical_op
);
676 OP(FILTER_OP_OR_S64
):
678 struct logical_op
*insn
= (struct logical_op
*) pc
;
680 /* If REG_R0 is nonzero, skip and evaluate to 1 */
682 if (unlikely(reg
[REG_R0
].v
!= 0)) {
684 dbg_printf("Jumping to bytecode offset %u\n",
685 (unsigned int) insn
->skip_offset
);
686 next_pc
= start_pc
+ insn
->skip_offset
;
688 next_pc
+= sizeof(struct logical_op
);
693 OP(FILTER_OP_AND_DOUBLE
):
695 struct logical_op
*insn
= (struct logical_op
*) pc
;
697 /* If REG_R0 is 0, skip and evaluate to 0 */
698 if ((reg
[REG_R0
].type
== REG_DOUBLE
&& unlikely(reg
[REG_R0
].d
== 0.0))
699 || (reg
[REG_R0
].type
== REG_S64
&& unlikely(reg
[REG_R0
].v
== 0))) {
700 dbg_printf("Jumping to bytecode offset %u\n",
701 (unsigned int) insn
->skip_offset
);
702 next_pc
= start_pc
+ insn
->skip_offset
;
704 next_pc
+= sizeof(struct logical_op
);
708 OP(FILTER_OP_OR_DOUBLE
):
710 struct logical_op
*insn
= (struct logical_op
*) pc
;
712 /* If REG_R0 is nonzero, skip and evaluate to 1 (in double) */
713 if ((reg
[REG_R0
].type
== REG_DOUBLE
&& unlikely(reg
[REG_R0
].d
!= 0.0))
714 || (reg
[REG_R0
].type
== REG_S64
&& unlikely(reg
[REG_R0
].v
!= 0))) {
716 dbg_printf("Jumping to bytecode offset %u\n",
717 (unsigned int) insn
->skip_offset
);
718 next_pc
= start_pc
+ insn
->skip_offset
;
720 next_pc
+= sizeof(struct logical_op
);
726 OP(FILTER_OP_LOAD_FIELD_REF_STRING
):
728 struct load_op
*insn
= (struct load_op
*) pc
;
729 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
731 dbg_printf("load field ref offset %u type string\n",
734 *(const char * const *) &filter_stack_data
[ref
->offset
];
735 reg
[insn
->reg
].type
= REG_STRING
;
736 reg
[insn
->reg
].seq_len
= UINT_MAX
;
737 reg
[insn
->reg
].literal
= 0;
738 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
739 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
743 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE
):
745 struct load_op
*insn
= (struct load_op
*) pc
;
746 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
748 dbg_printf("load field ref offset %u type sequence\n",
750 reg
[insn
->reg
].seq_len
=
751 *(unsigned long *) &filter_stack_data
[ref
->offset
];
753 *(const char **) (&filter_stack_data
[ref
->offset
754 + sizeof(unsigned long)]);
755 reg
[insn
->reg
].type
= REG_STRING
;
756 reg
[insn
->reg
].literal
= 0;
757 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
761 OP(FILTER_OP_LOAD_FIELD_REF_S64
):
763 struct load_op
*insn
= (struct load_op
*) pc
;
764 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
766 dbg_printf("load field ref offset %u type s64\n",
768 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
769 sizeof(struct literal_numeric
));
770 reg
[insn
->reg
].type
= REG_S64
;
771 reg
[insn
->reg
].literal
= 0;
772 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
773 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
777 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE
):
779 struct load_op
*insn
= (struct load_op
*) pc
;
780 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
782 dbg_printf("load field ref offset %u type double\n",
784 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
785 sizeof(struct literal_double
));
786 reg
[insn
->reg
].type
= REG_DOUBLE
;
787 reg
[insn
->reg
].literal
= 0;
788 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
789 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
793 OP(FILTER_OP_LOAD_STRING
):
795 struct load_op
*insn
= (struct load_op
*) pc
;
797 dbg_printf("load string %s\n", insn
->data
);
798 reg
[insn
->reg
].str
= insn
->data
;
799 reg
[insn
->reg
].type
= REG_STRING
;
800 reg
[insn
->reg
].seq_len
= UINT_MAX
;
801 reg
[insn
->reg
].literal
= 1;
802 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
806 OP(FILTER_OP_LOAD_S64
):
808 struct load_op
*insn
= (struct load_op
*) pc
;
810 memcpy(®
[insn
->reg
].v
, insn
->data
,
811 sizeof(struct literal_numeric
));
812 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
813 reg
[insn
->reg
].type
= REG_S64
;
814 reg
[insn
->reg
].literal
= 1;
815 next_pc
+= sizeof(struct load_op
)
816 + sizeof(struct literal_numeric
);
820 OP(FILTER_OP_LOAD_DOUBLE
):
822 struct load_op
*insn
= (struct load_op
*) pc
;
824 memcpy(®
[insn
->reg
].d
, insn
->data
,
825 sizeof(struct literal_double
));
826 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
827 reg
[insn
->reg
].type
= REG_DOUBLE
;
828 reg
[insn
->reg
].literal
= 1;
829 next_pc
+= sizeof(struct load_op
)
830 + sizeof(struct literal_double
);
836 /* return 0 (discard) on error */
848 int bin_op_compare_check(struct vreg reg
[NR_REG
], const char *str
)
850 switch (reg
[REG_R0
].type
) {
855 switch (reg
[REG_R1
].type
) {
868 switch (reg
[REG_R1
].type
) {
887 ERR("type mismatch for '%s' binary operator\n", str
);
892 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
894 void *pc
, *next_pc
, *start_pc
;
896 struct vreg reg
[NR_REG
];
899 for (i
= 0; i
< NR_REG
; i
++) {
900 reg
[i
].type
= REG_TYPE_UNKNOWN
;
904 start_pc
= &bytecode
->data
[0];
905 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
907 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
908 ERR("filter bytecode overflow\n");
912 dbg_printf("Validating op %s (%u)\n",
913 print_op((unsigned int) *(filter_opcode_t
*) pc
),
914 (unsigned int) *(filter_opcode_t
*) pc
);
915 switch (*(filter_opcode_t
*) pc
) {
916 case FILTER_OP_UNKNOWN
:
918 ERR("unknown bytecode op %u\n",
919 (unsigned int) *(filter_opcode_t
*) pc
);
923 case FILTER_OP_RETURN
:
932 case FILTER_OP_MINUS
:
933 case FILTER_OP_RSHIFT
:
934 case FILTER_OP_LSHIFT
:
935 case FILTER_OP_BIN_AND
:
936 case FILTER_OP_BIN_OR
:
937 case FILTER_OP_BIN_XOR
:
938 ERR("unsupported bytecode op %u\n",
939 (unsigned int) *(filter_opcode_t
*) pc
);
945 ret
= bin_op_compare_check(reg
, "==");
948 reg
[REG_R0
].type
= REG_S64
;
949 next_pc
+= sizeof(struct binary_op
);
954 ret
= bin_op_compare_check(reg
, "!=");
957 reg
[REG_R0
].type
= REG_S64
;
958 next_pc
+= sizeof(struct binary_op
);
963 ret
= bin_op_compare_check(reg
, ">");
966 reg
[REG_R0
].type
= REG_S64
;
967 next_pc
+= sizeof(struct binary_op
);
972 ret
= bin_op_compare_check(reg
, "<");
975 reg
[REG_R0
].type
= REG_S64
;
976 next_pc
+= sizeof(struct binary_op
);
981 ret
= bin_op_compare_check(reg
, ">=");
984 reg
[REG_R0
].type
= REG_S64
;
985 next_pc
+= sizeof(struct binary_op
);
990 ret
= bin_op_compare_check(reg
, "<=");
993 reg
[REG_R0
].type
= REG_S64
;
994 next_pc
+= sizeof(struct binary_op
);
998 case FILTER_OP_EQ_STRING
:
999 case FILTER_OP_NE_STRING
:
1000 case FILTER_OP_GT_STRING
:
1001 case FILTER_OP_LT_STRING
:
1002 case FILTER_OP_GE_STRING
:
1003 case FILTER_OP_LE_STRING
:
1005 if (reg
[REG_R0
].type
!= REG_STRING
1006 || reg
[REG_R1
].type
!= REG_STRING
) {
1007 ERR("Unexpected register type for string comparator\n");
1011 reg
[REG_R0
].type
= REG_S64
;
1012 next_pc
+= sizeof(struct binary_op
);
1016 case FILTER_OP_EQ_S64
:
1017 case FILTER_OP_NE_S64
:
1018 case FILTER_OP_GT_S64
:
1019 case FILTER_OP_LT_S64
:
1020 case FILTER_OP_GE_S64
:
1021 case FILTER_OP_LE_S64
:
1023 if (reg
[REG_R0
].type
!= REG_S64
1024 || reg
[REG_R1
].type
!= REG_S64
) {
1025 ERR("Unexpected register type for s64 comparator\n");
1029 reg
[REG_R0
].type
= REG_S64
;
1030 next_pc
+= sizeof(struct binary_op
);
1034 case FILTER_OP_EQ_DOUBLE
:
1035 case FILTER_OP_NE_DOUBLE
:
1036 case FILTER_OP_GT_DOUBLE
:
1037 case FILTER_OP_LT_DOUBLE
:
1038 case FILTER_OP_GE_DOUBLE
:
1039 case FILTER_OP_LE_DOUBLE
:
1041 if ((reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R0
].type
!= REG_S64
)
1042 || (reg
[REG_R1
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_S64
)) {
1043 ERR("Unexpected register type for double comparator\n");
1047 if (reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_DOUBLE
) {
1048 ERR("Double operator should have at least one double register\n");
1052 reg
[REG_R0
].type
= REG_DOUBLE
;
1053 next_pc
+= sizeof(struct binary_op
);
1058 case FILTER_OP_UNARY_PLUS
:
1059 case FILTER_OP_UNARY_MINUS
:
1060 case FILTER_OP_UNARY_NOT
:
1062 struct unary_op
*insn
= (struct unary_op
*) pc
;
1064 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1065 ERR("invalid register %u\n",
1066 (unsigned int) insn
->reg
);
1070 switch (reg
[insn
->reg
].type
) {
1072 ERR("unknown register type\n");
1077 ERR("Unary op can only be applied to numeric or floating point registers\n");
1085 next_pc
+= sizeof(struct unary_op
);
1089 case FILTER_OP_UNARY_PLUS_S64
:
1090 case FILTER_OP_UNARY_MINUS_S64
:
1091 case FILTER_OP_UNARY_NOT_S64
:
1093 struct unary_op
*insn
= (struct unary_op
*) pc
;
1095 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1096 ERR("invalid register %u\n",
1097 (unsigned int) insn
->reg
);
1101 if (reg
[insn
->reg
].type
!= REG_S64
) {
1102 ERR("Invalid register type\n");
1106 next_pc
+= sizeof(struct unary_op
);
1110 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1111 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1112 case FILTER_OP_UNARY_NOT_DOUBLE
:
1114 struct unary_op
*insn
= (struct unary_op
*) pc
;
1116 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1117 ERR("invalid register %u\n",
1118 (unsigned int) insn
->reg
);
1122 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
1123 ERR("Invalid register type\n");
1127 next_pc
+= sizeof(struct unary_op
);
1134 case FILTER_OP_AND_S64
:
1135 case FILTER_OP_OR_S64
:
1136 case FILTER_OP_AND_DOUBLE
:
1137 case FILTER_OP_OR_DOUBLE
:
1139 struct logical_op
*insn
= (struct logical_op
*) pc
;
1141 if (unlikely(reg
[REG_R0
].type
== REG_TYPE_UNKNOWN
1142 || reg
[REG_R1
].type
== REG_TYPE_UNKNOWN
1143 || reg
[REG_R0
].type
== REG_STRING
1144 || reg
[REG_R1
].type
== REG_STRING
)) {
1145 ERR("Logical comparator can only be applied to numeric and floating point registers\n");
1150 dbg_printf("Validate jumping to bytecode offset %u\n",
1151 (unsigned int) insn
->skip_offset
);
1152 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
1153 ERR("Loops are not allowed in bytecode\n");
1157 if (insn
->op
== FILTER_OP_AND_S64
1158 || insn
->op
== FILTER_OP_OR_S64
) {
1159 if (reg
[REG_R0
].type
!= REG_S64
1160 || reg
[REG_R1
].type
!= REG_S64
) {
1165 if (insn
->op
== FILTER_OP_AND_DOUBLE
1166 || insn
->op
== FILTER_OP_OR_DOUBLE
) {
1167 if (reg
[REG_R0
].type
!= REG_DOUBLE
1168 && reg
[REG_R1
].type
!= REG_DOUBLE
) {
1169 ERR("Double operator should have at least one double register\n");
1174 switch(reg
[REG_R0
].type
) {
1177 ERR("unknown register type\n");
1182 if (reg
[REG_R1
].type
== REG_S64
) {
1183 reg
[REG_R0
].type
= REG_S64
;
1185 reg
[REG_R0
].type
= REG_DOUBLE
;
1189 reg
[REG_R0
].type
= REG_DOUBLE
;
1192 next_pc
+= sizeof(struct logical_op
);
1197 case FILTER_OP_LOAD_FIELD_REF
:
1199 ERR("Unknown field ref type\n");
1203 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1204 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1206 struct load_op
*insn
= (struct load_op
*) pc
;
1207 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1209 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1210 ERR("invalid register %u\n",
1211 (unsigned int) insn
->reg
);
1215 dbg_printf("Validate load field ref offset %u type string\n",
1217 reg
[insn
->reg
].type
= REG_STRING
;
1218 reg
[insn
->reg
].literal
= 0;
1219 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1222 case FILTER_OP_LOAD_FIELD_REF_S64
:
1224 struct load_op
*insn
= (struct load_op
*) pc
;
1225 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1227 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1228 ERR("invalid register %u\n",
1229 (unsigned int) insn
->reg
);
1233 dbg_printf("Validate load field ref offset %u type s64\n",
1235 reg
[insn
->reg
].type
= REG_S64
;
1236 reg
[insn
->reg
].literal
= 0;
1237 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1240 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1242 struct load_op
*insn
= (struct load_op
*) pc
;
1243 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1245 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1246 ERR("invalid register %u\n",
1247 (unsigned int) insn
->reg
);
1251 dbg_printf("Validate load field ref offset %u type double\n",
1253 reg
[insn
->reg
].type
= REG_DOUBLE
;
1254 reg
[insn
->reg
].literal
= 0;
1255 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1259 case FILTER_OP_LOAD_STRING
:
1261 struct load_op
*insn
= (struct load_op
*) pc
;
1263 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1264 ERR("invalid register %u\n",
1265 (unsigned int) insn
->reg
);
1269 reg
[insn
->reg
].type
= REG_STRING
;
1270 reg
[insn
->reg
].literal
= 1;
1271 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1275 case FILTER_OP_LOAD_S64
:
1277 struct load_op
*insn
= (struct load_op
*) pc
;
1279 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1280 ERR("invalid register %u\n",
1281 (unsigned int) insn
->reg
);
1285 reg
[insn
->reg
].type
= REG_S64
;
1286 reg
[insn
->reg
].literal
= 1;
1287 next_pc
+= sizeof(struct load_op
)
1288 + sizeof(struct literal_numeric
);
1292 case FILTER_OP_LOAD_DOUBLE
:
1294 struct load_op
*insn
= (struct load_op
*) pc
;
1296 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1297 ERR("invalid register %u\n",
1298 (unsigned int) insn
->reg
);
1302 reg
[insn
->reg
].type
= REG_DOUBLE
;
1303 reg
[insn
->reg
].literal
= 1;
1304 next_pc
+= sizeof(struct load_op
)
1305 + sizeof(struct literal_double
);
1315 int lttng_filter_specialize_bytecode(struct bytecode_runtime
*bytecode
)
1317 void *pc
, *next_pc
, *start_pc
;
1319 struct vreg reg
[NR_REG
];
1322 for (i
= 0; i
< NR_REG
; i
++) {
1323 reg
[i
].type
= REG_TYPE_UNKNOWN
;
1327 start_pc
= &bytecode
->data
[0];
1328 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1330 switch (*(filter_opcode_t
*) pc
) {
1331 case FILTER_OP_UNKNOWN
:
1333 ERR("unknown bytecode op %u\n",
1334 (unsigned int) *(filter_opcode_t
*) pc
);
1338 case FILTER_OP_RETURN
:
1346 case FILTER_OP_PLUS
:
1347 case FILTER_OP_MINUS
:
1348 case FILTER_OP_RSHIFT
:
1349 case FILTER_OP_LSHIFT
:
1350 case FILTER_OP_BIN_AND
:
1351 case FILTER_OP_BIN_OR
:
1352 case FILTER_OP_BIN_XOR
:
1353 ERR("unsupported bytecode op %u\n",
1354 (unsigned int) *(filter_opcode_t
*) pc
);
1360 struct binary_op
*insn
= (struct binary_op
*) pc
;
1362 switch(reg
[REG_R0
].type
) {
1364 ERR("unknown register type\n");
1369 insn
->op
= FILTER_OP_EQ_STRING
;
1372 if (reg
[REG_R1
].type
== REG_S64
)
1373 insn
->op
= FILTER_OP_EQ_S64
;
1375 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1378 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1381 reg
[REG_R0
].type
= REG_S64
;
1382 next_pc
+= sizeof(struct binary_op
);
1388 struct binary_op
*insn
= (struct binary_op
*) pc
;
1390 switch(reg
[REG_R0
].type
) {
1392 ERR("unknown register type\n");
1397 insn
->op
= FILTER_OP_NE_STRING
;
1400 if (reg
[REG_R1
].type
== REG_S64
)
1401 insn
->op
= FILTER_OP_NE_S64
;
1403 insn
->op
= FILTER_OP_NE_DOUBLE
;
1406 insn
->op
= FILTER_OP_NE_DOUBLE
;
1409 reg
[REG_R0
].type
= REG_S64
;
1410 next_pc
+= sizeof(struct binary_op
);
1416 struct binary_op
*insn
= (struct binary_op
*) pc
;
1418 switch(reg
[REG_R0
].type
) {
1420 ERR("unknown register type\n");
1425 insn
->op
= FILTER_OP_GT_STRING
;
1428 if (reg
[REG_R1
].type
== REG_S64
)
1429 insn
->op
= FILTER_OP_GT_S64
;
1431 insn
->op
= FILTER_OP_GT_DOUBLE
;
1434 insn
->op
= FILTER_OP_GT_DOUBLE
;
1437 reg
[REG_R0
].type
= REG_S64
;
1438 next_pc
+= sizeof(struct binary_op
);
1444 struct binary_op
*insn
= (struct binary_op
*) pc
;
1446 switch(reg
[REG_R0
].type
) {
1448 ERR("unknown register type\n");
1453 insn
->op
= FILTER_OP_LT_STRING
;
1456 if (reg
[REG_R1
].type
== REG_S64
)
1457 insn
->op
= FILTER_OP_LT_S64
;
1459 insn
->op
= FILTER_OP_LT_DOUBLE
;
1462 insn
->op
= FILTER_OP_LT_DOUBLE
;
1465 reg
[REG_R0
].type
= REG_S64
;
1466 next_pc
+= sizeof(struct binary_op
);
1472 struct binary_op
*insn
= (struct binary_op
*) pc
;
1474 switch(reg
[REG_R0
].type
) {
1476 ERR("unknown register type\n");
1481 insn
->op
= FILTER_OP_GE_STRING
;
1484 if (reg
[REG_R1
].type
== REG_S64
)
1485 insn
->op
= FILTER_OP_GE_S64
;
1487 insn
->op
= FILTER_OP_GE_DOUBLE
;
1490 insn
->op
= FILTER_OP_GE_DOUBLE
;
1493 reg
[REG_R0
].type
= REG_S64
;
1494 next_pc
+= sizeof(struct binary_op
);
1499 struct binary_op
*insn
= (struct binary_op
*) pc
;
1501 switch(reg
[REG_R0
].type
) {
1503 ERR("unknown register type\n");
1508 insn
->op
= FILTER_OP_LE_STRING
;
1511 if (reg
[REG_R1
].type
== REG_S64
)
1512 insn
->op
= FILTER_OP_LE_S64
;
1514 insn
->op
= FILTER_OP_LE_DOUBLE
;
1517 insn
->op
= FILTER_OP_LE_DOUBLE
;
1520 reg
[REG_R0
].type
= REG_S64
;
1521 next_pc
+= sizeof(struct binary_op
);
1525 case FILTER_OP_EQ_STRING
:
1526 case FILTER_OP_NE_STRING
:
1527 case FILTER_OP_GT_STRING
:
1528 case FILTER_OP_LT_STRING
:
1529 case FILTER_OP_GE_STRING
:
1530 case FILTER_OP_LE_STRING
:
1531 case FILTER_OP_EQ_S64
:
1532 case FILTER_OP_NE_S64
:
1533 case FILTER_OP_GT_S64
:
1534 case FILTER_OP_LT_S64
:
1535 case FILTER_OP_GE_S64
:
1536 case FILTER_OP_LE_S64
:
1537 case FILTER_OP_EQ_DOUBLE
:
1538 case FILTER_OP_NE_DOUBLE
:
1539 case FILTER_OP_GT_DOUBLE
:
1540 case FILTER_OP_LT_DOUBLE
:
1541 case FILTER_OP_GE_DOUBLE
:
1542 case FILTER_OP_LE_DOUBLE
:
1544 reg
[REG_R0
].type
= REG_S64
;
1545 next_pc
+= sizeof(struct binary_op
);
1550 case FILTER_OP_UNARY_PLUS
:
1552 struct unary_op
*insn
= (struct unary_op
*) pc
;
1554 switch(reg
[insn
->reg
].type
) {
1556 ERR("unknown register type\n");
1561 insn
->op
= FILTER_OP_UNARY_PLUS_S64
;
1564 insn
->op
= FILTER_OP_UNARY_PLUS_DOUBLE
;
1567 next_pc
+= sizeof(struct unary_op
);
1571 case FILTER_OP_UNARY_MINUS
:
1573 struct unary_op
*insn
= (struct unary_op
*) pc
;
1575 switch(reg
[insn
->reg
].type
) {
1577 ERR("unknown register type\n");
1582 insn
->op
= FILTER_OP_UNARY_MINUS_S64
;
1585 insn
->op
= FILTER_OP_UNARY_MINUS_DOUBLE
;
1588 next_pc
+= sizeof(struct unary_op
);
1592 case FILTER_OP_UNARY_NOT
:
1594 struct unary_op
*insn
= (struct unary_op
*) pc
;
1596 switch(reg
[insn
->reg
].type
) {
1598 ERR("unknown register type\n");
1603 insn
->op
= FILTER_OP_UNARY_NOT_S64
;
1606 insn
->op
= FILTER_OP_UNARY_NOT_DOUBLE
;
1609 next_pc
+= sizeof(struct unary_op
);
1613 case FILTER_OP_UNARY_PLUS_S64
:
1614 case FILTER_OP_UNARY_MINUS_S64
:
1615 case FILTER_OP_UNARY_NOT_S64
:
1616 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1617 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1618 case FILTER_OP_UNARY_NOT_DOUBLE
:
1620 next_pc
+= sizeof(struct unary_op
);
1627 struct logical_op
*insn
= (struct logical_op
*) pc
;
1629 switch(reg
[REG_R0
].type
) {
1632 ERR("unknown register type\n");
1637 if (reg
[REG_R1
].type
== REG_S64
) {
1638 insn
->op
= FILTER_OP_AND_S64
;
1639 reg
[REG_R0
].type
= REG_S64
;
1641 insn
->op
= FILTER_OP_AND_DOUBLE
;
1642 reg
[REG_R0
].type
= REG_DOUBLE
;
1646 insn
->op
= FILTER_OP_AND_DOUBLE
;
1647 reg
[REG_R0
].type
= REG_DOUBLE
;
1650 next_pc
+= sizeof(struct logical_op
);
1655 struct logical_op
*insn
= (struct logical_op
*) pc
;
1657 switch(reg
[REG_R0
].type
) {
1660 ERR("unknown register type\n");
1665 if (reg
[REG_R1
].type
== REG_S64
) {
1666 insn
->op
= FILTER_OP_OR_S64
;
1667 reg
[REG_R0
].type
= REG_S64
;
1669 insn
->op
= FILTER_OP_OR_DOUBLE
;
1670 reg
[REG_R0
].type
= REG_DOUBLE
;
1674 insn
->op
= FILTER_OP_OR_DOUBLE
;
1675 reg
[REG_R0
].type
= REG_DOUBLE
;
1678 next_pc
+= sizeof(struct logical_op
);
1682 case FILTER_OP_AND_S64
:
1683 case FILTER_OP_OR_S64
:
1684 case FILTER_OP_AND_DOUBLE
:
1685 case FILTER_OP_OR_DOUBLE
:
1687 next_pc
+= sizeof(struct logical_op
);
1692 case FILTER_OP_LOAD_FIELD_REF
:
1694 ERR("Unknown field ref type\n");
1698 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1699 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1701 struct load_op
*insn
= (struct load_op
*) pc
;
1703 reg
[insn
->reg
].type
= REG_STRING
;
1704 reg
[insn
->reg
].literal
= 0;
1705 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1708 case FILTER_OP_LOAD_FIELD_REF_S64
:
1710 struct load_op
*insn
= (struct load_op
*) pc
;
1712 reg
[insn
->reg
].type
= REG_S64
;
1713 reg
[insn
->reg
].literal
= 0;
1714 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1717 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1719 struct load_op
*insn
= (struct load_op
*) pc
;
1721 reg
[insn
->reg
].type
= REG_DOUBLE
;
1722 reg
[insn
->reg
].literal
= 0;
1723 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1727 case FILTER_OP_LOAD_STRING
:
1729 struct load_op
*insn
= (struct load_op
*) pc
;
1731 reg
[insn
->reg
].type
= REG_STRING
;
1732 reg
[insn
->reg
].literal
= 1;
1733 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1737 case FILTER_OP_LOAD_S64
:
1739 struct load_op
*insn
= (struct load_op
*) pc
;
1741 reg
[insn
->reg
].type
= REG_S64
;
1742 reg
[insn
->reg
].literal
= 1;
1743 next_pc
+= sizeof(struct load_op
)
1744 + sizeof(struct literal_numeric
);
1748 case FILTER_OP_LOAD_DOUBLE
:
1750 struct load_op
*insn
= (struct load_op
*) pc
;
1752 reg
[insn
->reg
].type
= REG_DOUBLE
;
1753 reg
[insn
->reg
].literal
= 1;
1754 next_pc
+= sizeof(struct load_op
)
1755 + sizeof(struct literal_double
);
1767 int apply_field_reloc(struct ltt_event
*event
,
1768 struct bytecode_runtime
*runtime
,
1769 uint32_t runtime_len
,
1770 uint32_t reloc_offset
,
1771 const char *field_name
)
1773 const struct lttng_event_desc
*desc
;
1774 const struct lttng_event_field
*fields
, *field
= NULL
;
1775 unsigned int nr_fields
, i
;
1776 struct field_ref
*field_ref
;
1778 uint32_t field_offset
= 0;
1780 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1782 /* Ensure that the reloc is within the code */
1783 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1786 /* Lookup event by name */
1790 fields
= desc
->fields
;
1793 nr_fields
= desc
->nr_fields
;
1794 for (i
= 0; i
< nr_fields
; i
++) {
1795 if (!strcmp(fields
[i
].name
, field_name
)) {
1799 /* compute field offset */
1800 switch (fields
[i
].type
.atype
) {
1803 field_offset
+= sizeof(int64_t);
1806 case atype_sequence
:
1807 field_offset
+= sizeof(unsigned long);
1808 field_offset
+= sizeof(void *);
1811 field_offset
+= sizeof(void *);
1814 field_offset
+= sizeof(double);
1823 /* Check if field offset is too large for 16-bit offset */
1824 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1828 op
= (struct load_op
*) &runtime
->data
[reloc_offset
];
1829 field_ref
= (struct field_ref
*) op
->data
;
1830 switch (field
->type
.atype
) {
1833 op
->op
= FILTER_OP_LOAD_FIELD_REF_S64
;
1836 case atype_sequence
:
1837 op
->op
= FILTER_OP_LOAD_FIELD_REF_SEQUENCE
;
1840 op
->op
= FILTER_OP_LOAD_FIELD_REF_STRING
;
1843 op
->op
= FILTER_OP_LOAD_FIELD_REF_DOUBLE
;
1849 field_ref
->offset
= (uint16_t) field_offset
;
1854 * Take a bytecode with reloc table and link it to an event to create a
1858 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1859 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1861 int ret
, offset
, next_offset
;
1862 struct bytecode_runtime
*runtime
= NULL
;
1863 size_t runtime_alloc_len
;
1865 if (!filter_bytecode
)
1867 /* Even is not connected to any description */
1870 /* Bytecode already linked */
1871 if (event
->filter
|| event
->filter_data
)
1874 dbg_printf("Linking\n");
1876 /* We don't need the reloc table in the runtime */
1877 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
1878 runtime
= zmalloc(runtime_alloc_len
);
1883 runtime
->len
= filter_bytecode
->reloc_offset
;
1884 /* copy original bytecode */
1885 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
1887 * apply relocs. Those are a uint16_t (offset in bytecode)
1888 * followed by a string (field name).
1890 for (offset
= filter_bytecode
->reloc_offset
;
1891 offset
< filter_bytecode
->len
;
1892 offset
= next_offset
) {
1893 uint16_t reloc_offset
=
1894 *(uint16_t *) &filter_bytecode
->data
[offset
];
1895 const char *field_name
=
1896 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
1898 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1902 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1904 /* Validate bytecode */
1905 ret
= lttng_filter_validate_bytecode(runtime
);
1909 /* Specialize bytecode */
1910 ret
= lttng_filter_specialize_bytecode(runtime
);
1914 event
->filter_data
= runtime
;
1915 event
->filter
= lttng_filter_interpret_bytecode
;
1919 event
->filter
= lttng_filter_false
;
1924 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1925 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1929 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1931 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1936 * Link bytecode to all events for a wildcard. Skips events that already
1937 * have a bytecode linked.
1938 * We do not set each event's filter_bytecode field, because they do not
1939 * own the filter_bytecode: the wildcard owns it.
1941 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1943 struct ltt_event
*event
;
1946 if (!wildcard
->filter_bytecode
)
1949 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1952 ret
= _lttng_filter_event_link_bytecode(event
,
1953 wildcard
->filter_bytecode
);
1955 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1963 * Need to attach filter to an event before starting tracing for the
1964 * session. We own the filter_bytecode if we return success.
1966 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1967 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1969 if (event
->chan
->session
->been_active
)
1971 if (event
->filter_bytecode
)
1973 event
->filter_bytecode
= filter_bytecode
;
1978 * Need to attach filter to a wildcard before starting tracing for the
1979 * session. We own the filter_bytecode if we return success.
1981 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1982 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1984 if (wildcard
->chan
->session
->been_active
)
1986 if (wildcard
->filter_bytecode
)
1988 wildcard
->filter_bytecode
= filter_bytecode
;