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",
157 [ FILTER_OP_LOAD_FIELD_REF
] = "LOAD_FIELD_REF",
158 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = "LOAD_FIELD_REF_STRING",
159 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = "LOAD_FIELD_REF_SEQUENCE",
160 [ FILTER_OP_LOAD_FIELD_REF_S64
] = "LOAD_FIELD_REF_S64",
161 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = "LOAD_FIELD_REF_DOUBLE",
163 [ FILTER_OP_LOAD_STRING
] = "LOAD_STRING",
164 [ FILTER_OP_LOAD_S64
] = "LOAD_S64",
165 [ FILTER_OP_LOAD_DOUBLE
] = "LOAD_DOUBLE",
168 [ FILTER_OP_CAST_TO_S64
] = "CAST_TO_S64",
169 [ FILTER_OP_CAST_DOUBLE_TO_S64
] = "CAST_DOUBLE_TO_S64",
170 [ FILTER_OP_CAST_NOP
] = "CAST_NOP",
174 const char *print_op(enum filter_op op
)
176 if (op
>= NR_FILTER_OPS
)
183 * -1: wildcard found.
184 * -2: unknown escape char.
189 int parse_char(const char **p
)
209 int reg_strcmp(struct reg reg
[NR_REG
], const char *cmp_type
)
211 const char *p
= reg
[REG_R0
].str
, *q
= reg
[REG_R1
].str
;
218 if (unlikely(p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')) {
219 if (q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')
225 if (unlikely(q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')) {
226 if (p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')
232 if (reg
[REG_R0
].literal
) {
233 ret
= parse_char(&p
);
236 } else if (ret
== -2) {
239 /* else compare both char */
241 if (reg
[REG_R1
].literal
) {
242 ret
= parse_char(&q
);
245 } else if (ret
== -2) {
266 int lttng_filter_false(void *filter_data
,
267 const char *filter_stack_data
)
272 #ifdef INTERPRETER_USE_SWITCH
275 * Fallback for compilers that do not support taking address of labels.
279 start_pc = &bytecode->data[0]; \
280 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
282 dbg_printf("Executing op %s (%u)\n", \
283 print_op((unsigned int) *(filter_opcode_t *) pc), \
284 (unsigned int) *(filter_opcode_t *) pc); \
285 switch (*(filter_opcode_t *) pc) {
287 #define OP(name) case name
297 * Dispatch-table based interpreter.
301 start_pc = &bytecode->data[0]; \
302 pc = next_pc = start_pc; \
303 if (unlikely(pc - start_pc >= bytecode->len)) \
305 goto *dispatch[*(filter_opcode_t *) pc];
312 goto *dispatch[*(filter_opcode_t *) pc];
319 int lttng_filter_interpret_bytecode(void *filter_data
,
320 const char *filter_stack_data
)
322 struct bytecode_runtime
*bytecode
= filter_data
;
323 void *pc
, *next_pc
, *start_pc
;
326 struct reg reg
[NR_REG
];
327 #ifndef INTERPRETER_USE_SWITCH
328 static void *dispatch
[NR_FILTER_OPS
] = {
329 [ FILTER_OP_UNKNOWN
] = &&LABEL_FILTER_OP_UNKNOWN
,
331 [ FILTER_OP_RETURN
] = &&LABEL_FILTER_OP_RETURN
,
334 [ FILTER_OP_MUL
] = &&LABEL_FILTER_OP_MUL
,
335 [ FILTER_OP_DIV
] = &&LABEL_FILTER_OP_DIV
,
336 [ FILTER_OP_MOD
] = &&LABEL_FILTER_OP_MOD
,
337 [ FILTER_OP_PLUS
] = &&LABEL_FILTER_OP_PLUS
,
338 [ FILTER_OP_MINUS
] = &&LABEL_FILTER_OP_MINUS
,
339 [ FILTER_OP_RSHIFT
] = &&LABEL_FILTER_OP_RSHIFT
,
340 [ FILTER_OP_LSHIFT
] = &&LABEL_FILTER_OP_LSHIFT
,
341 [ FILTER_OP_BIN_AND
] = &&LABEL_FILTER_OP_BIN_AND
,
342 [ FILTER_OP_BIN_OR
] = &&LABEL_FILTER_OP_BIN_OR
,
343 [ FILTER_OP_BIN_XOR
] = &&LABEL_FILTER_OP_BIN_XOR
,
345 /* binary comparators */
346 [ FILTER_OP_EQ
] = &&LABEL_FILTER_OP_EQ
,
347 [ FILTER_OP_NE
] = &&LABEL_FILTER_OP_NE
,
348 [ FILTER_OP_GT
] = &&LABEL_FILTER_OP_GT
,
349 [ FILTER_OP_LT
] = &&LABEL_FILTER_OP_LT
,
350 [ FILTER_OP_GE
] = &&LABEL_FILTER_OP_GE
,
351 [ FILTER_OP_LE
] = &&LABEL_FILTER_OP_LE
,
353 /* string binary comparator */
354 [ FILTER_OP_EQ_STRING
] = &&LABEL_FILTER_OP_EQ_STRING
,
355 [ FILTER_OP_NE_STRING
] = &&LABEL_FILTER_OP_NE_STRING
,
356 [ FILTER_OP_GT_STRING
] = &&LABEL_FILTER_OP_GT_STRING
,
357 [ FILTER_OP_LT_STRING
] = &&LABEL_FILTER_OP_LT_STRING
,
358 [ FILTER_OP_GE_STRING
] = &&LABEL_FILTER_OP_GE_STRING
,
359 [ FILTER_OP_LE_STRING
] = &&LABEL_FILTER_OP_LE_STRING
,
361 /* s64 binary comparator */
362 [ FILTER_OP_EQ_S64
] = &&LABEL_FILTER_OP_EQ_S64
,
363 [ FILTER_OP_NE_S64
] = &&LABEL_FILTER_OP_NE_S64
,
364 [ FILTER_OP_GT_S64
] = &&LABEL_FILTER_OP_GT_S64
,
365 [ FILTER_OP_LT_S64
] = &&LABEL_FILTER_OP_LT_S64
,
366 [ FILTER_OP_GE_S64
] = &&LABEL_FILTER_OP_GE_S64
,
367 [ FILTER_OP_LE_S64
] = &&LABEL_FILTER_OP_LE_S64
,
369 /* double binary comparator */
370 [ FILTER_OP_EQ_DOUBLE
] = &&LABEL_FILTER_OP_EQ_DOUBLE
,
371 [ FILTER_OP_NE_DOUBLE
] = &&LABEL_FILTER_OP_NE_DOUBLE
,
372 [ FILTER_OP_GT_DOUBLE
] = &&LABEL_FILTER_OP_GT_DOUBLE
,
373 [ FILTER_OP_LT_DOUBLE
] = &&LABEL_FILTER_OP_LT_DOUBLE
,
374 [ FILTER_OP_GE_DOUBLE
] = &&LABEL_FILTER_OP_GE_DOUBLE
,
375 [ FILTER_OP_LE_DOUBLE
] = &&LABEL_FILTER_OP_LE_DOUBLE
,
378 [ FILTER_OP_UNARY_PLUS
] = &&LABEL_FILTER_OP_UNARY_PLUS
,
379 [ FILTER_OP_UNARY_MINUS
] = &&LABEL_FILTER_OP_UNARY_MINUS
,
380 [ FILTER_OP_UNARY_NOT
] = &&LABEL_FILTER_OP_UNARY_NOT
,
381 [ FILTER_OP_UNARY_PLUS_S64
] = &&LABEL_FILTER_OP_UNARY_PLUS_S64
,
382 [ FILTER_OP_UNARY_MINUS_S64
] = &&LABEL_FILTER_OP_UNARY_MINUS_S64
,
383 [ FILTER_OP_UNARY_NOT_S64
] = &&LABEL_FILTER_OP_UNARY_NOT_S64
,
384 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE
,
385 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE
,
386 [ FILTER_OP_UNARY_NOT_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE
,
389 [ FILTER_OP_AND
] = &&LABEL_FILTER_OP_AND
,
390 [ FILTER_OP_OR
] = &&LABEL_FILTER_OP_OR
,
393 [ FILTER_OP_LOAD_FIELD_REF
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF
,
394 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING
,
395 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE
,
396 [ FILTER_OP_LOAD_FIELD_REF_S64
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64
,
397 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE
,
399 [ FILTER_OP_LOAD_STRING
] = &&LABEL_FILTER_OP_LOAD_STRING
,
400 [ FILTER_OP_LOAD_S64
] = &&LABEL_FILTER_OP_LOAD_S64
,
401 [ FILTER_OP_LOAD_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_DOUBLE
,
404 [ FILTER_OP_CAST_TO_S64
] = &&LABEL_FILTER_OP_CAST_TO_S64
,
405 [ FILTER_OP_CAST_DOUBLE_TO_S64
] = &&LABEL_FILTER_OP_CAST_DOUBLE_TO_S64
,
406 [ FILTER_OP_CAST_NOP
] = &&LABEL_FILTER_OP_CAST_NOP
,
408 #endif /* #ifndef INTERPRETER_USE_SWITCH */
412 OP(FILTER_OP_UNKNOWN
):
413 OP(FILTER_OP_LOAD_FIELD_REF
):
414 #ifdef INTERPRETER_USE_SWITCH
416 #endif /* INTERPRETER_USE_SWITCH */
417 ERR("unknown bytecode op %u\n",
418 (unsigned int) *(filter_opcode_t
*) pc
);
422 OP(FILTER_OP_RETURN
):
433 OP(FILTER_OP_RSHIFT
):
434 OP(FILTER_OP_LSHIFT
):
435 OP(FILTER_OP_BIN_AND
):
436 OP(FILTER_OP_BIN_OR
):
437 OP(FILTER_OP_BIN_XOR
):
438 ERR("unsupported bytecode op %u\n",
439 (unsigned int) *(filter_opcode_t
*) pc
);
449 ERR("unsupported non-specialized bytecode op %u\n",
450 (unsigned int) *(filter_opcode_t
*) pc
);
454 OP(FILTER_OP_EQ_STRING
):
456 reg
[REG_R0
].v
= (reg_strcmp(reg
, "==") == 0);
457 reg
[REG_R0
].type
= REG_S64
;
458 next_pc
+= sizeof(struct binary_op
);
461 OP(FILTER_OP_NE_STRING
):
463 reg
[REG_R0
].v
= (reg_strcmp(reg
, "!=") != 0);
464 reg
[REG_R0
].type
= REG_S64
;
465 next_pc
+= sizeof(struct binary_op
);
468 OP(FILTER_OP_GT_STRING
):
470 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">") > 0);
471 reg
[REG_R0
].type
= REG_S64
;
472 next_pc
+= sizeof(struct binary_op
);
475 OP(FILTER_OP_LT_STRING
):
477 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<") < 0);
478 reg
[REG_R0
].type
= REG_S64
;
479 next_pc
+= sizeof(struct binary_op
);
482 OP(FILTER_OP_GE_STRING
):
484 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">=") >= 0);
485 reg
[REG_R0
].type
= REG_S64
;
486 next_pc
+= sizeof(struct binary_op
);
489 OP(FILTER_OP_LE_STRING
):
491 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<=") <= 0);
492 reg
[REG_R0
].type
= REG_S64
;
493 next_pc
+= sizeof(struct binary_op
);
497 OP(FILTER_OP_EQ_S64
):
499 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].v
);
500 reg
[REG_R0
].type
= REG_S64
;
501 next_pc
+= sizeof(struct binary_op
);
504 OP(FILTER_OP_NE_S64
):
506 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].v
);
507 reg
[REG_R0
].type
= REG_S64
;
508 next_pc
+= sizeof(struct binary_op
);
511 OP(FILTER_OP_GT_S64
):
513 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].v
);
514 reg
[REG_R0
].type
= REG_S64
;
515 next_pc
+= sizeof(struct binary_op
);
518 OP(FILTER_OP_LT_S64
):
520 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].v
);
521 reg
[REG_R0
].type
= REG_S64
;
522 next_pc
+= sizeof(struct binary_op
);
525 OP(FILTER_OP_GE_S64
):
527 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].v
);
528 reg
[REG_R0
].type
= REG_S64
;
529 next_pc
+= sizeof(struct binary_op
);
532 OP(FILTER_OP_LE_S64
):
534 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].v
);
535 reg
[REG_R0
].type
= REG_S64
;
536 next_pc
+= sizeof(struct binary_op
);
540 OP(FILTER_OP_EQ_DOUBLE
):
542 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
543 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
544 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
545 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
546 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].d
);
547 reg
[REG_R0
].type
= REG_S64
;
548 next_pc
+= sizeof(struct binary_op
);
551 OP(FILTER_OP_NE_DOUBLE
):
553 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
554 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
555 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
556 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
557 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].d
);
558 reg
[REG_R0
].type
= REG_S64
;
559 next_pc
+= sizeof(struct binary_op
);
562 OP(FILTER_OP_GT_DOUBLE
):
564 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
565 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
566 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
567 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
568 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].d
);
569 reg
[REG_R0
].type
= REG_S64
;
570 next_pc
+= sizeof(struct binary_op
);
573 OP(FILTER_OP_LT_DOUBLE
):
575 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
576 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
577 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
578 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
579 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].d
);
580 reg
[REG_R0
].type
= REG_S64
;
581 next_pc
+= sizeof(struct binary_op
);
584 OP(FILTER_OP_GE_DOUBLE
):
586 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
587 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
588 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
589 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
590 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].d
);
591 reg
[REG_R0
].type
= REG_S64
;
592 next_pc
+= sizeof(struct binary_op
);
595 OP(FILTER_OP_LE_DOUBLE
):
597 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
598 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
599 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
600 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
601 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].d
);
602 reg
[REG_R0
].type
= REG_S64
;
603 next_pc
+= sizeof(struct binary_op
);
608 OP(FILTER_OP_UNARY_PLUS
):
609 OP(FILTER_OP_UNARY_MINUS
):
610 OP(FILTER_OP_UNARY_NOT
):
611 ERR("unsupported non-specialized bytecode op %u\n",
612 (unsigned int) *(filter_opcode_t
*) pc
);
617 OP(FILTER_OP_UNARY_PLUS_S64
):
618 OP(FILTER_OP_UNARY_PLUS_DOUBLE
):
620 next_pc
+= sizeof(struct unary_op
);
623 OP(FILTER_OP_UNARY_MINUS_S64
):
625 struct unary_op
*insn
= (struct unary_op
*) pc
;
627 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
628 next_pc
+= sizeof(struct unary_op
);
631 OP(FILTER_OP_UNARY_MINUS_DOUBLE
):
633 struct unary_op
*insn
= (struct unary_op
*) pc
;
635 reg
[insn
->reg
].d
= -reg
[insn
->reg
].d
;
636 next_pc
+= sizeof(struct unary_op
);
639 OP(FILTER_OP_UNARY_NOT_S64
):
641 struct unary_op
*insn
= (struct unary_op
*) pc
;
643 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
644 next_pc
+= sizeof(struct unary_op
);
647 OP(FILTER_OP_UNARY_NOT_DOUBLE
):
649 struct unary_op
*insn
= (struct unary_op
*) pc
;
651 reg
[insn
->reg
].d
= !reg
[insn
->reg
].d
;
652 next_pc
+= sizeof(struct unary_op
);
659 struct logical_op
*insn
= (struct logical_op
*) pc
;
661 /* If REG_R0 is 0, skip and evaluate to 0 */
662 if (unlikely(reg
[REG_R0
].v
== 0)) {
663 dbg_printf("Jumping to bytecode offset %u\n",
664 (unsigned int) insn
->skip_offset
);
665 next_pc
= start_pc
+ insn
->skip_offset
;
667 next_pc
+= sizeof(struct logical_op
);
673 struct logical_op
*insn
= (struct logical_op
*) pc
;
675 /* If REG_R0 is nonzero, skip and evaluate to 1 */
677 if (unlikely(reg
[REG_R0
].v
!= 0)) {
679 dbg_printf("Jumping to bytecode offset %u\n",
680 (unsigned int) insn
->skip_offset
);
681 next_pc
= start_pc
+ insn
->skip_offset
;
683 next_pc
+= sizeof(struct logical_op
);
690 OP(FILTER_OP_LOAD_FIELD_REF_STRING
):
692 struct load_op
*insn
= (struct load_op
*) pc
;
693 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
695 dbg_printf("load field ref offset %u type string\n",
698 *(const char * const *) &filter_stack_data
[ref
->offset
];
699 if (unlikely(!reg
[insn
->reg
].str
)) {
700 dbg_printf("Filter warning: loading a NULL string.\n");
704 reg
[insn
->reg
].type
= REG_STRING
;
705 reg
[insn
->reg
].seq_len
= UINT_MAX
;
706 reg
[insn
->reg
].literal
= 0;
707 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
708 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
712 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE
):
714 struct load_op
*insn
= (struct load_op
*) pc
;
715 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
717 dbg_printf("load field ref offset %u type sequence\n",
719 reg
[insn
->reg
].seq_len
=
720 *(unsigned long *) &filter_stack_data
[ref
->offset
];
722 *(const char **) (&filter_stack_data
[ref
->offset
723 + sizeof(unsigned long)]);
724 if (unlikely(!reg
[insn
->reg
].str
)) {
725 dbg_printf("Filter warning: loading a NULL sequence.\n");
729 reg
[insn
->reg
].type
= REG_STRING
;
730 reg
[insn
->reg
].literal
= 0;
731 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
735 OP(FILTER_OP_LOAD_FIELD_REF_S64
):
737 struct load_op
*insn
= (struct load_op
*) pc
;
738 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
740 dbg_printf("load field ref offset %u type s64\n",
742 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
743 sizeof(struct literal_numeric
));
744 reg
[insn
->reg
].type
= REG_S64
;
745 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
746 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
750 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE
):
752 struct load_op
*insn
= (struct load_op
*) pc
;
753 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
755 dbg_printf("load field ref offset %u type double\n",
757 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
758 sizeof(struct literal_double
));
759 reg
[insn
->reg
].type
= REG_DOUBLE
;
760 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
761 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
765 OP(FILTER_OP_LOAD_STRING
):
767 struct load_op
*insn
= (struct load_op
*) pc
;
769 dbg_printf("load string %s\n", insn
->data
);
770 reg
[insn
->reg
].str
= insn
->data
;
771 reg
[insn
->reg
].type
= REG_STRING
;
772 reg
[insn
->reg
].seq_len
= UINT_MAX
;
773 reg
[insn
->reg
].literal
= 1;
774 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
778 OP(FILTER_OP_LOAD_S64
):
780 struct load_op
*insn
= (struct load_op
*) pc
;
782 memcpy(®
[insn
->reg
].v
, insn
->data
,
783 sizeof(struct literal_numeric
));
784 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
785 reg
[insn
->reg
].type
= REG_S64
;
786 next_pc
+= sizeof(struct load_op
)
787 + sizeof(struct literal_numeric
);
791 OP(FILTER_OP_LOAD_DOUBLE
):
793 struct load_op
*insn
= (struct load_op
*) pc
;
795 memcpy(®
[insn
->reg
].d
, insn
->data
,
796 sizeof(struct literal_double
));
797 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
798 reg
[insn
->reg
].type
= REG_DOUBLE
;
799 next_pc
+= sizeof(struct load_op
)
800 + sizeof(struct literal_double
);
805 OP(FILTER_OP_CAST_TO_S64
):
806 ERR("unsupported non-specialized bytecode op %u\n",
807 (unsigned int) *(filter_opcode_t
*) pc
);
811 OP(FILTER_OP_CAST_DOUBLE_TO_S64
):
813 struct cast_op
*insn
= (struct cast_op
*) pc
;
815 reg
[insn
->reg
].v
= (int64_t) reg
[insn
->reg
].d
;
816 reg
[insn
->reg
].type
= REG_S64
;
817 next_pc
+= sizeof(struct cast_op
);
821 OP(FILTER_OP_CAST_NOP
):
823 next_pc
+= sizeof(struct cast_op
);
829 /* return 0 (discard) on error */
841 int bin_op_compare_check(struct vreg reg
[NR_REG
], const char *str
)
843 switch (reg
[REG_R0
].type
) {
848 switch (reg
[REG_R1
].type
) {
861 switch (reg
[REG_R1
].type
) {
880 ERR("type mismatch for '%s' binary operator\n", str
);
885 * Validate bytecode range overflow within the validation pass.
886 * Called for each instruction encountered.
889 int bytecode_validate_overflow(struct bytecode_runtime
*bytecode
,
890 void *start_pc
, void *pc
)
894 switch (*(filter_opcode_t
*) pc
) {
895 case FILTER_OP_UNKNOWN
:
898 ERR("unknown bytecode op %u\n",
899 (unsigned int) *(filter_opcode_t
*) pc
);
904 case FILTER_OP_RETURN
:
906 if (unlikely(pc
+ sizeof(struct return_op
)
907 > start_pc
+ bytecode
->len
)) {
918 case FILTER_OP_MINUS
:
919 case FILTER_OP_RSHIFT
:
920 case FILTER_OP_LSHIFT
:
921 case FILTER_OP_BIN_AND
:
922 case FILTER_OP_BIN_OR
:
923 case FILTER_OP_BIN_XOR
:
925 ERR("unsupported bytecode op %u\n",
926 (unsigned int) *(filter_opcode_t
*) pc
);
937 case FILTER_OP_EQ_STRING
:
938 case FILTER_OP_NE_STRING
:
939 case FILTER_OP_GT_STRING
:
940 case FILTER_OP_LT_STRING
:
941 case FILTER_OP_GE_STRING
:
942 case FILTER_OP_LE_STRING
:
943 case FILTER_OP_EQ_S64
:
944 case FILTER_OP_NE_S64
:
945 case FILTER_OP_GT_S64
:
946 case FILTER_OP_LT_S64
:
947 case FILTER_OP_GE_S64
:
948 case FILTER_OP_LE_S64
:
949 case FILTER_OP_EQ_DOUBLE
:
950 case FILTER_OP_NE_DOUBLE
:
951 case FILTER_OP_GT_DOUBLE
:
952 case FILTER_OP_LT_DOUBLE
:
953 case FILTER_OP_GE_DOUBLE
:
954 case FILTER_OP_LE_DOUBLE
:
956 if (unlikely(pc
+ sizeof(struct binary_op
)
957 > start_pc
+ bytecode
->len
)) {
964 case FILTER_OP_UNARY_PLUS
:
965 case FILTER_OP_UNARY_MINUS
:
966 case FILTER_OP_UNARY_NOT
:
967 case FILTER_OP_UNARY_PLUS_S64
:
968 case FILTER_OP_UNARY_MINUS_S64
:
969 case FILTER_OP_UNARY_NOT_S64
:
970 case FILTER_OP_UNARY_PLUS_DOUBLE
:
971 case FILTER_OP_UNARY_MINUS_DOUBLE
:
972 case FILTER_OP_UNARY_NOT_DOUBLE
:
974 if (unlikely(pc
+ sizeof(struct unary_op
)
975 > start_pc
+ bytecode
->len
)) {
985 if (unlikely(pc
+ sizeof(struct logical_op
)
986 > start_pc
+ bytecode
->len
)) {
993 case FILTER_OP_LOAD_FIELD_REF
:
995 ERR("Unknown field ref type\n");
999 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1000 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1001 case FILTER_OP_LOAD_FIELD_REF_S64
:
1002 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1004 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct field_ref
)
1005 > start_pc
+ bytecode
->len
)) {
1011 case FILTER_OP_LOAD_STRING
:
1013 struct load_op
*insn
= (struct load_op
*) pc
;
1014 uint32_t str_len
, maxlen
;
1016 if (unlikely(pc
+ sizeof(struct load_op
)
1017 > start_pc
+ bytecode
->len
)) {
1022 maxlen
= start_pc
+ bytecode
->len
- pc
- sizeof(struct load_op
);
1023 str_len
= strnlen(insn
->data
, maxlen
);
1024 if (unlikely(str_len
>= maxlen
)) {
1025 /* Final '\0' not found within range */
1031 case FILTER_OP_LOAD_S64
:
1033 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct literal_numeric
)
1034 > start_pc
+ bytecode
->len
)) {
1040 case FILTER_OP_LOAD_DOUBLE
:
1042 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct literal_double
)
1043 > start_pc
+ bytecode
->len
)) {
1049 case FILTER_OP_CAST_TO_S64
:
1050 case FILTER_OP_CAST_DOUBLE_TO_S64
:
1051 case FILTER_OP_CAST_NOP
:
1053 if (unlikely(pc
+ sizeof(struct cast_op
)
1054 > start_pc
+ bytecode
->len
)) {
1065 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
1067 void *pc
, *next_pc
, *start_pc
;
1069 struct vreg reg
[NR_REG
];
1072 for (i
= 0; i
< NR_REG
; i
++) {
1073 reg
[i
].type
= REG_TYPE_UNKNOWN
;
1077 start_pc
= &bytecode
->data
[0];
1078 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1080 if (bytecode_validate_overflow(bytecode
, start_pc
, pc
) != 0) {
1081 ERR("filter bytecode overflow\n");
1085 dbg_printf("Validating op %s (%u)\n",
1086 print_op((unsigned int) *(filter_opcode_t
*) pc
),
1087 (unsigned int) *(filter_opcode_t
*) pc
);
1088 switch (*(filter_opcode_t
*) pc
) {
1089 case FILTER_OP_UNKNOWN
:
1091 ERR("unknown bytecode op %u\n",
1092 (unsigned int) *(filter_opcode_t
*) pc
);
1096 case FILTER_OP_RETURN
:
1104 case FILTER_OP_PLUS
:
1105 case FILTER_OP_MINUS
:
1106 case FILTER_OP_RSHIFT
:
1107 case FILTER_OP_LSHIFT
:
1108 case FILTER_OP_BIN_AND
:
1109 case FILTER_OP_BIN_OR
:
1110 case FILTER_OP_BIN_XOR
:
1111 ERR("unsupported bytecode op %u\n",
1112 (unsigned int) *(filter_opcode_t
*) pc
);
1118 ret
= bin_op_compare_check(reg
, "==");
1121 reg
[REG_R0
].type
= REG_S64
;
1122 next_pc
+= sizeof(struct binary_op
);
1127 ret
= bin_op_compare_check(reg
, "!=");
1130 reg
[REG_R0
].type
= REG_S64
;
1131 next_pc
+= sizeof(struct binary_op
);
1136 ret
= bin_op_compare_check(reg
, ">");
1139 reg
[REG_R0
].type
= REG_S64
;
1140 next_pc
+= sizeof(struct binary_op
);
1145 ret
= bin_op_compare_check(reg
, "<");
1148 reg
[REG_R0
].type
= REG_S64
;
1149 next_pc
+= sizeof(struct binary_op
);
1154 ret
= bin_op_compare_check(reg
, ">=");
1157 reg
[REG_R0
].type
= REG_S64
;
1158 next_pc
+= sizeof(struct binary_op
);
1163 ret
= bin_op_compare_check(reg
, "<=");
1166 reg
[REG_R0
].type
= REG_S64
;
1167 next_pc
+= sizeof(struct binary_op
);
1171 case FILTER_OP_EQ_STRING
:
1172 case FILTER_OP_NE_STRING
:
1173 case FILTER_OP_GT_STRING
:
1174 case FILTER_OP_LT_STRING
:
1175 case FILTER_OP_GE_STRING
:
1176 case FILTER_OP_LE_STRING
:
1178 if (reg
[REG_R0
].type
!= REG_STRING
1179 || reg
[REG_R1
].type
!= REG_STRING
) {
1180 ERR("Unexpected register type for string comparator\n");
1184 reg
[REG_R0
].type
= REG_S64
;
1185 next_pc
+= sizeof(struct binary_op
);
1189 case FILTER_OP_EQ_S64
:
1190 case FILTER_OP_NE_S64
:
1191 case FILTER_OP_GT_S64
:
1192 case FILTER_OP_LT_S64
:
1193 case FILTER_OP_GE_S64
:
1194 case FILTER_OP_LE_S64
:
1196 if (reg
[REG_R0
].type
!= REG_S64
1197 || reg
[REG_R1
].type
!= REG_S64
) {
1198 ERR("Unexpected register type for s64 comparator\n");
1202 reg
[REG_R0
].type
= REG_S64
;
1203 next_pc
+= sizeof(struct binary_op
);
1207 case FILTER_OP_EQ_DOUBLE
:
1208 case FILTER_OP_NE_DOUBLE
:
1209 case FILTER_OP_GT_DOUBLE
:
1210 case FILTER_OP_LT_DOUBLE
:
1211 case FILTER_OP_GE_DOUBLE
:
1212 case FILTER_OP_LE_DOUBLE
:
1214 if ((reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R0
].type
!= REG_S64
)
1215 || (reg
[REG_R1
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_S64
)) {
1216 ERR("Unexpected register type for double comparator\n");
1220 if (reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_DOUBLE
) {
1221 ERR("Double operator should have at least one double register\n");
1225 reg
[REG_R0
].type
= REG_DOUBLE
;
1226 next_pc
+= sizeof(struct binary_op
);
1231 case FILTER_OP_UNARY_PLUS
:
1232 case FILTER_OP_UNARY_MINUS
:
1233 case FILTER_OP_UNARY_NOT
:
1235 struct unary_op
*insn
= (struct unary_op
*) pc
;
1237 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1238 ERR("invalid register %u\n",
1239 (unsigned int) insn
->reg
);
1243 switch (reg
[insn
->reg
].type
) {
1245 ERR("unknown register type\n");
1250 ERR("Unary op can only be applied to numeric or floating point registers\n");
1258 next_pc
+= sizeof(struct unary_op
);
1262 case FILTER_OP_UNARY_PLUS_S64
:
1263 case FILTER_OP_UNARY_MINUS_S64
:
1264 case FILTER_OP_UNARY_NOT_S64
:
1266 struct unary_op
*insn
= (struct unary_op
*) pc
;
1268 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1269 ERR("invalid register %u\n",
1270 (unsigned int) insn
->reg
);
1274 if (reg
[insn
->reg
].type
!= REG_S64
) {
1275 ERR("Invalid register type\n");
1279 next_pc
+= sizeof(struct unary_op
);
1283 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1284 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1285 case FILTER_OP_UNARY_NOT_DOUBLE
:
1287 struct unary_op
*insn
= (struct unary_op
*) pc
;
1289 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1290 ERR("invalid register %u\n",
1291 (unsigned int) insn
->reg
);
1295 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
1296 ERR("Invalid register type\n");
1300 next_pc
+= sizeof(struct unary_op
);
1308 struct logical_op
*insn
= (struct logical_op
*) pc
;
1310 if (reg
[REG_R0
].type
!= REG_S64
) {
1311 ERR("Logical comparator expects S64 register\n");
1316 dbg_printf("Validate jumping to bytecode offset %u\n",
1317 (unsigned int) insn
->skip_offset
);
1318 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
1319 ERR("Loops are not allowed in bytecode\n");
1323 next_pc
+= sizeof(struct logical_op
);
1328 case FILTER_OP_LOAD_FIELD_REF
:
1330 ERR("Unknown field ref type\n");
1334 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1335 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1337 struct load_op
*insn
= (struct load_op
*) pc
;
1338 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1340 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1341 ERR("invalid register %u\n",
1342 (unsigned int) insn
->reg
);
1346 dbg_printf("Validate load field ref offset %u type string\n",
1348 reg
[insn
->reg
].type
= REG_STRING
;
1349 reg
[insn
->reg
].literal
= 0;
1350 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1353 case FILTER_OP_LOAD_FIELD_REF_S64
:
1355 struct load_op
*insn
= (struct load_op
*) pc
;
1356 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1358 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1359 ERR("invalid register %u\n",
1360 (unsigned int) insn
->reg
);
1364 dbg_printf("Validate load field ref offset %u type s64\n",
1366 reg
[insn
->reg
].type
= REG_S64
;
1367 reg
[insn
->reg
].literal
= 0;
1368 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1371 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1373 struct load_op
*insn
= (struct load_op
*) pc
;
1374 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1376 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1377 ERR("invalid register %u\n",
1378 (unsigned int) insn
->reg
);
1382 dbg_printf("Validate load field ref offset %u type double\n",
1384 reg
[insn
->reg
].type
= REG_DOUBLE
;
1385 reg
[insn
->reg
].literal
= 0;
1386 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1390 case FILTER_OP_LOAD_STRING
:
1392 struct load_op
*insn
= (struct load_op
*) pc
;
1394 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1395 ERR("invalid register %u\n",
1396 (unsigned int) insn
->reg
);
1400 reg
[insn
->reg
].type
= REG_STRING
;
1401 reg
[insn
->reg
].literal
= 1;
1402 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1406 case FILTER_OP_LOAD_S64
:
1408 struct load_op
*insn
= (struct load_op
*) pc
;
1410 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1411 ERR("invalid register %u\n",
1412 (unsigned int) insn
->reg
);
1416 reg
[insn
->reg
].type
= REG_S64
;
1417 reg
[insn
->reg
].literal
= 1;
1418 next_pc
+= sizeof(struct load_op
)
1419 + sizeof(struct literal_numeric
);
1423 case FILTER_OP_LOAD_DOUBLE
:
1425 struct load_op
*insn
= (struct load_op
*) pc
;
1427 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1428 ERR("invalid register %u\n",
1429 (unsigned int) insn
->reg
);
1433 reg
[insn
->reg
].type
= REG_DOUBLE
;
1434 reg
[insn
->reg
].literal
= 1;
1435 next_pc
+= sizeof(struct load_op
)
1436 + sizeof(struct literal_double
);
1440 case FILTER_OP_CAST_TO_S64
:
1441 case FILTER_OP_CAST_DOUBLE_TO_S64
:
1443 struct cast_op
*insn
= (struct cast_op
*) pc
;
1445 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1446 ERR("invalid register %u\n",
1447 (unsigned int) insn
->reg
);
1451 switch (reg
[insn
->reg
].type
) {
1453 ERR("unknown register type\n");
1458 ERR("Cast op can only be applied to numeric or floating point registers\n");
1466 if (insn
->op
== FILTER_OP_CAST_DOUBLE_TO_S64
) {
1467 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
1468 ERR("Cast expects double\n");
1473 reg
[insn
->reg
].type
= REG_S64
;
1474 next_pc
+= sizeof(struct cast_op
);
1477 case FILTER_OP_CAST_NOP
:
1479 next_pc
+= sizeof(struct cast_op
);
1490 int lttng_filter_specialize_bytecode(struct bytecode_runtime
*bytecode
)
1492 void *pc
, *next_pc
, *start_pc
;
1494 struct vreg reg
[NR_REG
];
1497 for (i
= 0; i
< NR_REG
; i
++) {
1498 reg
[i
].type
= REG_TYPE_UNKNOWN
;
1502 start_pc
= &bytecode
->data
[0];
1503 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1505 switch (*(filter_opcode_t
*) pc
) {
1506 case FILTER_OP_UNKNOWN
:
1508 ERR("unknown bytecode op %u\n",
1509 (unsigned int) *(filter_opcode_t
*) pc
);
1513 case FILTER_OP_RETURN
:
1521 case FILTER_OP_PLUS
:
1522 case FILTER_OP_MINUS
:
1523 case FILTER_OP_RSHIFT
:
1524 case FILTER_OP_LSHIFT
:
1525 case FILTER_OP_BIN_AND
:
1526 case FILTER_OP_BIN_OR
:
1527 case FILTER_OP_BIN_XOR
:
1528 ERR("unsupported bytecode op %u\n",
1529 (unsigned int) *(filter_opcode_t
*) pc
);
1535 struct binary_op
*insn
= (struct binary_op
*) pc
;
1537 switch(reg
[REG_R0
].type
) {
1539 ERR("unknown register type\n");
1544 insn
->op
= FILTER_OP_EQ_STRING
;
1547 if (reg
[REG_R1
].type
== REG_S64
)
1548 insn
->op
= FILTER_OP_EQ_S64
;
1550 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1553 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1556 reg
[REG_R0
].type
= REG_S64
;
1557 next_pc
+= sizeof(struct binary_op
);
1563 struct binary_op
*insn
= (struct binary_op
*) pc
;
1565 switch(reg
[REG_R0
].type
) {
1567 ERR("unknown register type\n");
1572 insn
->op
= FILTER_OP_NE_STRING
;
1575 if (reg
[REG_R1
].type
== REG_S64
)
1576 insn
->op
= FILTER_OP_NE_S64
;
1578 insn
->op
= FILTER_OP_NE_DOUBLE
;
1581 insn
->op
= FILTER_OP_NE_DOUBLE
;
1584 reg
[REG_R0
].type
= REG_S64
;
1585 next_pc
+= sizeof(struct binary_op
);
1591 struct binary_op
*insn
= (struct binary_op
*) pc
;
1593 switch(reg
[REG_R0
].type
) {
1595 ERR("unknown register type\n");
1600 insn
->op
= FILTER_OP_GT_STRING
;
1603 if (reg
[REG_R1
].type
== REG_S64
)
1604 insn
->op
= FILTER_OP_GT_S64
;
1606 insn
->op
= FILTER_OP_GT_DOUBLE
;
1609 insn
->op
= FILTER_OP_GT_DOUBLE
;
1612 reg
[REG_R0
].type
= REG_S64
;
1613 next_pc
+= sizeof(struct binary_op
);
1619 struct binary_op
*insn
= (struct binary_op
*) pc
;
1621 switch(reg
[REG_R0
].type
) {
1623 ERR("unknown register type\n");
1628 insn
->op
= FILTER_OP_LT_STRING
;
1631 if (reg
[REG_R1
].type
== REG_S64
)
1632 insn
->op
= FILTER_OP_LT_S64
;
1634 insn
->op
= FILTER_OP_LT_DOUBLE
;
1637 insn
->op
= FILTER_OP_LT_DOUBLE
;
1640 reg
[REG_R0
].type
= REG_S64
;
1641 next_pc
+= sizeof(struct binary_op
);
1647 struct binary_op
*insn
= (struct binary_op
*) pc
;
1649 switch(reg
[REG_R0
].type
) {
1651 ERR("unknown register type\n");
1656 insn
->op
= FILTER_OP_GE_STRING
;
1659 if (reg
[REG_R1
].type
== REG_S64
)
1660 insn
->op
= FILTER_OP_GE_S64
;
1662 insn
->op
= FILTER_OP_GE_DOUBLE
;
1665 insn
->op
= FILTER_OP_GE_DOUBLE
;
1668 reg
[REG_R0
].type
= REG_S64
;
1669 next_pc
+= sizeof(struct binary_op
);
1674 struct binary_op
*insn
= (struct binary_op
*) pc
;
1676 switch(reg
[REG_R0
].type
) {
1678 ERR("unknown register type\n");
1683 insn
->op
= FILTER_OP_LE_STRING
;
1686 if (reg
[REG_R1
].type
== REG_S64
)
1687 insn
->op
= FILTER_OP_LE_S64
;
1689 insn
->op
= FILTER_OP_LE_DOUBLE
;
1692 insn
->op
= FILTER_OP_LE_DOUBLE
;
1695 reg
[REG_R0
].type
= REG_S64
;
1696 next_pc
+= sizeof(struct binary_op
);
1700 case FILTER_OP_EQ_STRING
:
1701 case FILTER_OP_NE_STRING
:
1702 case FILTER_OP_GT_STRING
:
1703 case FILTER_OP_LT_STRING
:
1704 case FILTER_OP_GE_STRING
:
1705 case FILTER_OP_LE_STRING
:
1706 case FILTER_OP_EQ_S64
:
1707 case FILTER_OP_NE_S64
:
1708 case FILTER_OP_GT_S64
:
1709 case FILTER_OP_LT_S64
:
1710 case FILTER_OP_GE_S64
:
1711 case FILTER_OP_LE_S64
:
1712 case FILTER_OP_EQ_DOUBLE
:
1713 case FILTER_OP_NE_DOUBLE
:
1714 case FILTER_OP_GT_DOUBLE
:
1715 case FILTER_OP_LT_DOUBLE
:
1716 case FILTER_OP_GE_DOUBLE
:
1717 case FILTER_OP_LE_DOUBLE
:
1719 reg
[REG_R0
].type
= REG_S64
;
1720 next_pc
+= sizeof(struct binary_op
);
1725 case FILTER_OP_UNARY_PLUS
:
1727 struct unary_op
*insn
= (struct unary_op
*) pc
;
1729 switch(reg
[insn
->reg
].type
) {
1731 ERR("unknown register type\n");
1736 insn
->op
= FILTER_OP_UNARY_PLUS_S64
;
1739 insn
->op
= FILTER_OP_UNARY_PLUS_DOUBLE
;
1742 next_pc
+= sizeof(struct unary_op
);
1746 case FILTER_OP_UNARY_MINUS
:
1748 struct unary_op
*insn
= (struct unary_op
*) pc
;
1750 switch(reg
[insn
->reg
].type
) {
1752 ERR("unknown register type\n");
1757 insn
->op
= FILTER_OP_UNARY_MINUS_S64
;
1760 insn
->op
= FILTER_OP_UNARY_MINUS_DOUBLE
;
1763 next_pc
+= sizeof(struct unary_op
);
1767 case FILTER_OP_UNARY_NOT
:
1769 struct unary_op
*insn
= (struct unary_op
*) pc
;
1771 switch(reg
[insn
->reg
].type
) {
1773 ERR("unknown register type\n");
1778 insn
->op
= FILTER_OP_UNARY_NOT_S64
;
1781 insn
->op
= FILTER_OP_UNARY_NOT_DOUBLE
;
1784 next_pc
+= sizeof(struct unary_op
);
1788 case FILTER_OP_UNARY_PLUS_S64
:
1789 case FILTER_OP_UNARY_MINUS_S64
:
1790 case FILTER_OP_UNARY_NOT_S64
:
1791 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1792 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1793 case FILTER_OP_UNARY_NOT_DOUBLE
:
1795 next_pc
+= sizeof(struct unary_op
);
1803 next_pc
+= sizeof(struct logical_op
);
1808 case FILTER_OP_LOAD_FIELD_REF
:
1810 ERR("Unknown field ref type\n");
1814 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1815 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1817 struct load_op
*insn
= (struct load_op
*) pc
;
1819 reg
[insn
->reg
].type
= REG_STRING
;
1820 reg
[insn
->reg
].literal
= 0;
1821 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1824 case FILTER_OP_LOAD_FIELD_REF_S64
:
1826 struct load_op
*insn
= (struct load_op
*) pc
;
1828 reg
[insn
->reg
].type
= REG_S64
;
1829 reg
[insn
->reg
].literal
= 0;
1830 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1833 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1835 struct load_op
*insn
= (struct load_op
*) pc
;
1837 reg
[insn
->reg
].type
= REG_DOUBLE
;
1838 reg
[insn
->reg
].literal
= 0;
1839 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1843 case FILTER_OP_LOAD_STRING
:
1845 struct load_op
*insn
= (struct load_op
*) pc
;
1847 reg
[insn
->reg
].type
= REG_STRING
;
1848 reg
[insn
->reg
].literal
= 1;
1849 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1853 case FILTER_OP_LOAD_S64
:
1855 struct load_op
*insn
= (struct load_op
*) pc
;
1857 reg
[insn
->reg
].type
= REG_S64
;
1858 reg
[insn
->reg
].literal
= 1;
1859 next_pc
+= sizeof(struct load_op
)
1860 + sizeof(struct literal_numeric
);
1864 case FILTER_OP_LOAD_DOUBLE
:
1866 struct load_op
*insn
= (struct load_op
*) pc
;
1868 reg
[insn
->reg
].type
= REG_DOUBLE
;
1869 reg
[insn
->reg
].literal
= 1;
1870 next_pc
+= sizeof(struct load_op
)
1871 + sizeof(struct literal_double
);
1876 case FILTER_OP_CAST_TO_S64
:
1878 struct cast_op
*insn
= (struct cast_op
*) pc
;
1880 switch (reg
[insn
->reg
].type
) {
1882 ERR("unknown register type\n");
1887 ERR("Cast op can only be applied to numeric or floating point registers\n");
1891 insn
->op
= FILTER_OP_CAST_NOP
;
1894 insn
->op
= FILTER_OP_CAST_DOUBLE_TO_S64
;
1897 reg
[insn
->reg
].type
= REG_S64
;
1898 next_pc
+= sizeof(struct cast_op
);
1901 case FILTER_OP_CAST_DOUBLE_TO_S64
:
1903 struct cast_op
*insn
= (struct cast_op
*) pc
;
1905 reg
[insn
->reg
].type
= REG_S64
;
1906 next_pc
+= sizeof(struct cast_op
);
1909 case FILTER_OP_CAST_NOP
:
1911 next_pc
+= sizeof(struct cast_op
);
1923 int apply_field_reloc(struct ltt_event
*event
,
1924 struct bytecode_runtime
*runtime
,
1925 uint32_t runtime_len
,
1926 uint32_t reloc_offset
,
1927 const char *field_name
)
1929 const struct lttng_event_desc
*desc
;
1930 const struct lttng_event_field
*fields
, *field
= NULL
;
1931 unsigned int nr_fields
, i
;
1932 struct field_ref
*field_ref
;
1934 uint32_t field_offset
= 0;
1936 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1938 /* Ensure that the reloc is within the code */
1939 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1942 /* Lookup event by name */
1946 fields
= desc
->fields
;
1949 nr_fields
= desc
->nr_fields
;
1950 for (i
= 0; i
< nr_fields
; i
++) {
1951 if (!strcmp(fields
[i
].name
, field_name
)) {
1955 /* compute field offset */
1956 switch (fields
[i
].type
.atype
) {
1959 field_offset
+= sizeof(int64_t);
1962 case atype_sequence
:
1963 field_offset
+= sizeof(unsigned long);
1964 field_offset
+= sizeof(void *);
1967 field_offset
+= sizeof(void *);
1970 field_offset
+= sizeof(double);
1979 /* Check if field offset is too large for 16-bit offset */
1980 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1984 op
= (struct load_op
*) &runtime
->data
[reloc_offset
];
1985 field_ref
= (struct field_ref
*) op
->data
;
1986 switch (field
->type
.atype
) {
1989 op
->op
= FILTER_OP_LOAD_FIELD_REF_S64
;
1992 case atype_sequence
:
1993 op
->op
= FILTER_OP_LOAD_FIELD_REF_SEQUENCE
;
1996 op
->op
= FILTER_OP_LOAD_FIELD_REF_STRING
;
1999 op
->op
= FILTER_OP_LOAD_FIELD_REF_DOUBLE
;
2005 field_ref
->offset
= (uint16_t) field_offset
;
2010 * Take a bytecode with reloc table and link it to an event to create a
2014 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
2015 struct lttng_ust_filter_bytecode
*filter_bytecode
)
2017 int ret
, offset
, next_offset
;
2018 struct bytecode_runtime
*runtime
= NULL
;
2019 size_t runtime_alloc_len
;
2021 if (!filter_bytecode
)
2023 /* Even is not connected to any description */
2026 /* Bytecode already linked */
2027 if (event
->filter
|| event
->filter_data
)
2030 dbg_printf("Linking\n");
2032 /* We don't need the reloc table in the runtime */
2033 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
2034 runtime
= zmalloc(runtime_alloc_len
);
2039 runtime
->len
= filter_bytecode
->reloc_offset
;
2040 /* copy original bytecode */
2041 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
2043 * apply relocs. Those are a uint16_t (offset in bytecode)
2044 * followed by a string (field name).
2046 for (offset
= filter_bytecode
->reloc_offset
;
2047 offset
< filter_bytecode
->len
;
2048 offset
= next_offset
) {
2049 uint16_t reloc_offset
=
2050 *(uint16_t *) &filter_bytecode
->data
[offset
];
2051 const char *field_name
=
2052 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
2054 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
2058 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
2060 /* Validate bytecode */
2061 ret
= lttng_filter_validate_bytecode(runtime
);
2065 /* Specialize bytecode */
2066 ret
= lttng_filter_specialize_bytecode(runtime
);
2070 event
->filter_data
= runtime
;
2071 event
->filter
= lttng_filter_interpret_bytecode
;
2075 event
->filter
= lttng_filter_false
;
2080 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
2081 struct lttng_ust_filter_bytecode
*filter_bytecode
)
2085 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
2087 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
2092 * Link bytecode to all events for a wildcard. Skips events that already
2093 * have a bytecode linked.
2094 * We do not set each event's filter_bytecode field, because they do not
2095 * own the filter_bytecode: the wildcard owns it.
2097 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
2099 struct ltt_event
*event
;
2102 if (!wildcard
->filter_bytecode
)
2105 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
2108 ret
= _lttng_filter_event_link_bytecode(event
,
2109 wildcard
->filter_bytecode
);
2111 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
2119 * Need to attach filter to an event before starting tracing for the
2120 * session. We own the filter_bytecode if we return success.
2122 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
2123 struct lttng_ust_filter_bytecode
*filter_bytecode
)
2125 if (event
->chan
->session
->been_active
)
2127 if (event
->filter_bytecode
)
2129 event
->filter_bytecode
= filter_bytecode
;
2134 * Need to attach filter to a wildcard before starting tracing for the
2135 * session. We own the filter_bytecode if we return success.
2137 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
2138 struct lttng_ust_filter_bytecode
*filter_bytecode
)
2140 if (wildcard
->chan
->session
->been_active
)
2142 if (wildcard
->filter_bytecode
)
2144 wildcard
->filter_bytecode
= filter_bytecode
;