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 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
887 void *pc
, *next_pc
, *start_pc
;
889 struct vreg reg
[NR_REG
];
892 for (i
= 0; i
< NR_REG
; i
++) {
893 reg
[i
].type
= REG_TYPE_UNKNOWN
;
897 start_pc
= &bytecode
->data
[0];
898 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
900 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
901 ERR("filter bytecode overflow\n");
905 dbg_printf("Validating op %s (%u)\n",
906 print_op((unsigned int) *(filter_opcode_t
*) pc
),
907 (unsigned int) *(filter_opcode_t
*) pc
);
908 switch (*(filter_opcode_t
*) pc
) {
909 case FILTER_OP_UNKNOWN
:
911 ERR("unknown bytecode op %u\n",
912 (unsigned int) *(filter_opcode_t
*) pc
);
916 case FILTER_OP_RETURN
:
925 case FILTER_OP_MINUS
:
926 case FILTER_OP_RSHIFT
:
927 case FILTER_OP_LSHIFT
:
928 case FILTER_OP_BIN_AND
:
929 case FILTER_OP_BIN_OR
:
930 case FILTER_OP_BIN_XOR
:
931 ERR("unsupported bytecode op %u\n",
932 (unsigned int) *(filter_opcode_t
*) pc
);
938 ret
= bin_op_compare_check(reg
, "==");
941 reg
[REG_R0
].type
= REG_S64
;
942 next_pc
+= sizeof(struct binary_op
);
947 ret
= bin_op_compare_check(reg
, "!=");
950 reg
[REG_R0
].type
= REG_S64
;
951 next_pc
+= sizeof(struct binary_op
);
956 ret
= bin_op_compare_check(reg
, ">");
959 reg
[REG_R0
].type
= REG_S64
;
960 next_pc
+= sizeof(struct binary_op
);
965 ret
= bin_op_compare_check(reg
, "<");
968 reg
[REG_R0
].type
= REG_S64
;
969 next_pc
+= sizeof(struct binary_op
);
974 ret
= bin_op_compare_check(reg
, ">=");
977 reg
[REG_R0
].type
= REG_S64
;
978 next_pc
+= sizeof(struct binary_op
);
983 ret
= bin_op_compare_check(reg
, "<=");
986 reg
[REG_R0
].type
= REG_S64
;
987 next_pc
+= sizeof(struct binary_op
);
991 case FILTER_OP_EQ_STRING
:
992 case FILTER_OP_NE_STRING
:
993 case FILTER_OP_GT_STRING
:
994 case FILTER_OP_LT_STRING
:
995 case FILTER_OP_GE_STRING
:
996 case FILTER_OP_LE_STRING
:
998 if (reg
[REG_R0
].type
!= REG_STRING
999 || reg
[REG_R1
].type
!= REG_STRING
) {
1000 ERR("Unexpected register type for string comparator\n");
1004 reg
[REG_R0
].type
= REG_S64
;
1005 next_pc
+= sizeof(struct binary_op
);
1009 case FILTER_OP_EQ_S64
:
1010 case FILTER_OP_NE_S64
:
1011 case FILTER_OP_GT_S64
:
1012 case FILTER_OP_LT_S64
:
1013 case FILTER_OP_GE_S64
:
1014 case FILTER_OP_LE_S64
:
1016 if (reg
[REG_R0
].type
!= REG_S64
1017 || reg
[REG_R1
].type
!= REG_S64
) {
1018 ERR("Unexpected register type for s64 comparator\n");
1022 reg
[REG_R0
].type
= REG_S64
;
1023 next_pc
+= sizeof(struct binary_op
);
1027 case FILTER_OP_EQ_DOUBLE
:
1028 case FILTER_OP_NE_DOUBLE
:
1029 case FILTER_OP_GT_DOUBLE
:
1030 case FILTER_OP_LT_DOUBLE
:
1031 case FILTER_OP_GE_DOUBLE
:
1032 case FILTER_OP_LE_DOUBLE
:
1034 if ((reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R0
].type
!= REG_S64
)
1035 || (reg
[REG_R1
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_S64
)) {
1036 ERR("Unexpected register type for double comparator\n");
1040 if (reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_DOUBLE
) {
1041 ERR("Double operator should have at least one double register\n");
1045 reg
[REG_R0
].type
= REG_DOUBLE
;
1046 next_pc
+= sizeof(struct binary_op
);
1051 case FILTER_OP_UNARY_PLUS
:
1052 case FILTER_OP_UNARY_MINUS
:
1053 case FILTER_OP_UNARY_NOT
:
1055 struct unary_op
*insn
= (struct unary_op
*) pc
;
1057 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1058 ERR("invalid register %u\n",
1059 (unsigned int) insn
->reg
);
1063 switch (reg
[insn
->reg
].type
) {
1065 ERR("unknown register type\n");
1070 ERR("Unary op can only be applied to numeric or floating point registers\n");
1078 next_pc
+= sizeof(struct unary_op
);
1082 case FILTER_OP_UNARY_PLUS_S64
:
1083 case FILTER_OP_UNARY_MINUS_S64
:
1084 case FILTER_OP_UNARY_NOT_S64
:
1086 struct unary_op
*insn
= (struct unary_op
*) pc
;
1088 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1089 ERR("invalid register %u\n",
1090 (unsigned int) insn
->reg
);
1094 if (reg
[insn
->reg
].type
!= REG_S64
) {
1095 ERR("Invalid register type\n");
1099 next_pc
+= sizeof(struct unary_op
);
1103 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1104 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1105 case FILTER_OP_UNARY_NOT_DOUBLE
:
1107 struct unary_op
*insn
= (struct unary_op
*) pc
;
1109 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1110 ERR("invalid register %u\n",
1111 (unsigned int) insn
->reg
);
1115 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
1116 ERR("Invalid register type\n");
1120 next_pc
+= sizeof(struct unary_op
);
1128 struct logical_op
*insn
= (struct logical_op
*) pc
;
1130 if (reg
[REG_R0
].type
!= REG_S64
) {
1131 ERR("Logical comparator expects S64 register\n");
1136 dbg_printf("Validate jumping to bytecode offset %u\n",
1137 (unsigned int) insn
->skip_offset
);
1138 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
1139 ERR("Loops are not allowed in bytecode\n");
1143 next_pc
+= sizeof(struct logical_op
);
1148 case FILTER_OP_LOAD_FIELD_REF
:
1150 ERR("Unknown field ref type\n");
1154 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1155 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1157 struct load_op
*insn
= (struct load_op
*) pc
;
1158 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1160 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1161 ERR("invalid register %u\n",
1162 (unsigned int) insn
->reg
);
1166 dbg_printf("Validate load field ref offset %u type string\n",
1168 reg
[insn
->reg
].type
= REG_STRING
;
1169 reg
[insn
->reg
].literal
= 0;
1170 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1173 case FILTER_OP_LOAD_FIELD_REF_S64
:
1175 struct load_op
*insn
= (struct load_op
*) pc
;
1176 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1178 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1179 ERR("invalid register %u\n",
1180 (unsigned int) insn
->reg
);
1184 dbg_printf("Validate load field ref offset %u type s64\n",
1186 reg
[insn
->reg
].type
= REG_S64
;
1187 reg
[insn
->reg
].literal
= 0;
1188 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1191 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1193 struct load_op
*insn
= (struct load_op
*) pc
;
1194 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1196 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1197 ERR("invalid register %u\n",
1198 (unsigned int) insn
->reg
);
1202 dbg_printf("Validate load field ref offset %u type double\n",
1204 reg
[insn
->reg
].type
= REG_DOUBLE
;
1205 reg
[insn
->reg
].literal
= 0;
1206 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1210 case FILTER_OP_LOAD_STRING
:
1212 struct load_op
*insn
= (struct load_op
*) pc
;
1214 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1215 ERR("invalid register %u\n",
1216 (unsigned int) insn
->reg
);
1220 reg
[insn
->reg
].type
= REG_STRING
;
1221 reg
[insn
->reg
].literal
= 1;
1222 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1226 case FILTER_OP_LOAD_S64
:
1228 struct load_op
*insn
= (struct load_op
*) pc
;
1230 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1231 ERR("invalid register %u\n",
1232 (unsigned int) insn
->reg
);
1236 reg
[insn
->reg
].type
= REG_S64
;
1237 reg
[insn
->reg
].literal
= 1;
1238 next_pc
+= sizeof(struct load_op
)
1239 + sizeof(struct literal_numeric
);
1243 case FILTER_OP_LOAD_DOUBLE
:
1245 struct load_op
*insn
= (struct load_op
*) pc
;
1247 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1248 ERR("invalid register %u\n",
1249 (unsigned int) insn
->reg
);
1253 reg
[insn
->reg
].type
= REG_DOUBLE
;
1254 reg
[insn
->reg
].literal
= 1;
1255 next_pc
+= sizeof(struct load_op
)
1256 + sizeof(struct literal_double
);
1260 case FILTER_OP_CAST_TO_S64
:
1261 case FILTER_OP_CAST_DOUBLE_TO_S64
:
1263 struct cast_op
*insn
= (struct cast_op
*) pc
;
1265 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1266 ERR("invalid register %u\n",
1267 (unsigned int) insn
->reg
);
1271 switch (reg
[insn
->reg
].type
) {
1273 ERR("unknown register type\n");
1278 ERR("Cast op can only be applied to numeric or floating point registers\n");
1286 if (insn
->op
== FILTER_OP_CAST_DOUBLE_TO_S64
) {
1287 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
1288 ERR("Cast expects double\n");
1293 reg
[insn
->reg
].type
= REG_S64
;
1294 next_pc
+= sizeof(struct cast_op
);
1297 case FILTER_OP_CAST_NOP
:
1299 next_pc
+= sizeof(struct cast_op
);
1310 int lttng_filter_specialize_bytecode(struct bytecode_runtime
*bytecode
)
1312 void *pc
, *next_pc
, *start_pc
;
1314 struct vreg reg
[NR_REG
];
1317 for (i
= 0; i
< NR_REG
; i
++) {
1318 reg
[i
].type
= REG_TYPE_UNKNOWN
;
1322 start_pc
= &bytecode
->data
[0];
1323 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1325 switch (*(filter_opcode_t
*) pc
) {
1326 case FILTER_OP_UNKNOWN
:
1328 ERR("unknown bytecode op %u\n",
1329 (unsigned int) *(filter_opcode_t
*) pc
);
1333 case FILTER_OP_RETURN
:
1341 case FILTER_OP_PLUS
:
1342 case FILTER_OP_MINUS
:
1343 case FILTER_OP_RSHIFT
:
1344 case FILTER_OP_LSHIFT
:
1345 case FILTER_OP_BIN_AND
:
1346 case FILTER_OP_BIN_OR
:
1347 case FILTER_OP_BIN_XOR
:
1348 ERR("unsupported bytecode op %u\n",
1349 (unsigned int) *(filter_opcode_t
*) pc
);
1355 struct binary_op
*insn
= (struct binary_op
*) pc
;
1357 switch(reg
[REG_R0
].type
) {
1359 ERR("unknown register type\n");
1364 insn
->op
= FILTER_OP_EQ_STRING
;
1367 if (reg
[REG_R1
].type
== REG_S64
)
1368 insn
->op
= FILTER_OP_EQ_S64
;
1370 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1373 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1376 reg
[REG_R0
].type
= REG_S64
;
1377 next_pc
+= sizeof(struct binary_op
);
1383 struct binary_op
*insn
= (struct binary_op
*) pc
;
1385 switch(reg
[REG_R0
].type
) {
1387 ERR("unknown register type\n");
1392 insn
->op
= FILTER_OP_NE_STRING
;
1395 if (reg
[REG_R1
].type
== REG_S64
)
1396 insn
->op
= FILTER_OP_NE_S64
;
1398 insn
->op
= FILTER_OP_NE_DOUBLE
;
1401 insn
->op
= FILTER_OP_NE_DOUBLE
;
1404 reg
[REG_R0
].type
= REG_S64
;
1405 next_pc
+= sizeof(struct binary_op
);
1411 struct binary_op
*insn
= (struct binary_op
*) pc
;
1413 switch(reg
[REG_R0
].type
) {
1415 ERR("unknown register type\n");
1420 insn
->op
= FILTER_OP_GT_STRING
;
1423 if (reg
[REG_R1
].type
== REG_S64
)
1424 insn
->op
= FILTER_OP_GT_S64
;
1426 insn
->op
= FILTER_OP_GT_DOUBLE
;
1429 insn
->op
= FILTER_OP_GT_DOUBLE
;
1432 reg
[REG_R0
].type
= REG_S64
;
1433 next_pc
+= sizeof(struct binary_op
);
1439 struct binary_op
*insn
= (struct binary_op
*) pc
;
1441 switch(reg
[REG_R0
].type
) {
1443 ERR("unknown register type\n");
1448 insn
->op
= FILTER_OP_LT_STRING
;
1451 if (reg
[REG_R1
].type
== REG_S64
)
1452 insn
->op
= FILTER_OP_LT_S64
;
1454 insn
->op
= FILTER_OP_LT_DOUBLE
;
1457 insn
->op
= FILTER_OP_LT_DOUBLE
;
1460 reg
[REG_R0
].type
= REG_S64
;
1461 next_pc
+= sizeof(struct binary_op
);
1467 struct binary_op
*insn
= (struct binary_op
*) pc
;
1469 switch(reg
[REG_R0
].type
) {
1471 ERR("unknown register type\n");
1476 insn
->op
= FILTER_OP_GE_STRING
;
1479 if (reg
[REG_R1
].type
== REG_S64
)
1480 insn
->op
= FILTER_OP_GE_S64
;
1482 insn
->op
= FILTER_OP_GE_DOUBLE
;
1485 insn
->op
= FILTER_OP_GE_DOUBLE
;
1488 reg
[REG_R0
].type
= REG_S64
;
1489 next_pc
+= sizeof(struct binary_op
);
1494 struct binary_op
*insn
= (struct binary_op
*) pc
;
1496 switch(reg
[REG_R0
].type
) {
1498 ERR("unknown register type\n");
1503 insn
->op
= FILTER_OP_LE_STRING
;
1506 if (reg
[REG_R1
].type
== REG_S64
)
1507 insn
->op
= FILTER_OP_LE_S64
;
1509 insn
->op
= FILTER_OP_LE_DOUBLE
;
1512 insn
->op
= FILTER_OP_LE_DOUBLE
;
1515 reg
[REG_R0
].type
= REG_S64
;
1516 next_pc
+= sizeof(struct binary_op
);
1520 case FILTER_OP_EQ_STRING
:
1521 case FILTER_OP_NE_STRING
:
1522 case FILTER_OP_GT_STRING
:
1523 case FILTER_OP_LT_STRING
:
1524 case FILTER_OP_GE_STRING
:
1525 case FILTER_OP_LE_STRING
:
1526 case FILTER_OP_EQ_S64
:
1527 case FILTER_OP_NE_S64
:
1528 case FILTER_OP_GT_S64
:
1529 case FILTER_OP_LT_S64
:
1530 case FILTER_OP_GE_S64
:
1531 case FILTER_OP_LE_S64
:
1532 case FILTER_OP_EQ_DOUBLE
:
1533 case FILTER_OP_NE_DOUBLE
:
1534 case FILTER_OP_GT_DOUBLE
:
1535 case FILTER_OP_LT_DOUBLE
:
1536 case FILTER_OP_GE_DOUBLE
:
1537 case FILTER_OP_LE_DOUBLE
:
1539 reg
[REG_R0
].type
= REG_S64
;
1540 next_pc
+= sizeof(struct binary_op
);
1545 case FILTER_OP_UNARY_PLUS
:
1547 struct unary_op
*insn
= (struct unary_op
*) pc
;
1549 switch(reg
[insn
->reg
].type
) {
1551 ERR("unknown register type\n");
1556 insn
->op
= FILTER_OP_UNARY_PLUS_S64
;
1559 insn
->op
= FILTER_OP_UNARY_PLUS_DOUBLE
;
1562 next_pc
+= sizeof(struct unary_op
);
1566 case FILTER_OP_UNARY_MINUS
:
1568 struct unary_op
*insn
= (struct unary_op
*) pc
;
1570 switch(reg
[insn
->reg
].type
) {
1572 ERR("unknown register type\n");
1577 insn
->op
= FILTER_OP_UNARY_MINUS_S64
;
1580 insn
->op
= FILTER_OP_UNARY_MINUS_DOUBLE
;
1583 next_pc
+= sizeof(struct unary_op
);
1587 case FILTER_OP_UNARY_NOT
:
1589 struct unary_op
*insn
= (struct unary_op
*) pc
;
1591 switch(reg
[insn
->reg
].type
) {
1593 ERR("unknown register type\n");
1598 insn
->op
= FILTER_OP_UNARY_NOT_S64
;
1601 insn
->op
= FILTER_OP_UNARY_NOT_DOUBLE
;
1604 next_pc
+= sizeof(struct unary_op
);
1608 case FILTER_OP_UNARY_PLUS_S64
:
1609 case FILTER_OP_UNARY_MINUS_S64
:
1610 case FILTER_OP_UNARY_NOT_S64
:
1611 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1612 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1613 case FILTER_OP_UNARY_NOT_DOUBLE
:
1615 next_pc
+= sizeof(struct unary_op
);
1623 next_pc
+= sizeof(struct logical_op
);
1628 case FILTER_OP_LOAD_FIELD_REF
:
1630 ERR("Unknown field ref type\n");
1634 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1635 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1637 struct load_op
*insn
= (struct load_op
*) pc
;
1639 reg
[insn
->reg
].type
= REG_STRING
;
1640 reg
[insn
->reg
].literal
= 0;
1641 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1644 case FILTER_OP_LOAD_FIELD_REF_S64
:
1646 struct load_op
*insn
= (struct load_op
*) pc
;
1648 reg
[insn
->reg
].type
= REG_S64
;
1649 reg
[insn
->reg
].literal
= 0;
1650 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1653 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1655 struct load_op
*insn
= (struct load_op
*) pc
;
1657 reg
[insn
->reg
].type
= REG_DOUBLE
;
1658 reg
[insn
->reg
].literal
= 0;
1659 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1663 case FILTER_OP_LOAD_STRING
:
1665 struct load_op
*insn
= (struct load_op
*) pc
;
1667 reg
[insn
->reg
].type
= REG_STRING
;
1668 reg
[insn
->reg
].literal
= 1;
1669 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1673 case FILTER_OP_LOAD_S64
:
1675 struct load_op
*insn
= (struct load_op
*) pc
;
1677 reg
[insn
->reg
].type
= REG_S64
;
1678 reg
[insn
->reg
].literal
= 1;
1679 next_pc
+= sizeof(struct load_op
)
1680 + sizeof(struct literal_numeric
);
1684 case FILTER_OP_LOAD_DOUBLE
:
1686 struct load_op
*insn
= (struct load_op
*) pc
;
1688 reg
[insn
->reg
].type
= REG_DOUBLE
;
1689 reg
[insn
->reg
].literal
= 1;
1690 next_pc
+= sizeof(struct load_op
)
1691 + sizeof(struct literal_double
);
1696 case FILTER_OP_CAST_TO_S64
:
1698 struct cast_op
*insn
= (struct cast_op
*) pc
;
1700 switch (reg
[insn
->reg
].type
) {
1702 ERR("unknown register type\n");
1707 ERR("Cast op can only be applied to numeric or floating point registers\n");
1711 insn
->op
= FILTER_OP_CAST_NOP
;
1714 insn
->op
= FILTER_OP_CAST_DOUBLE_TO_S64
;
1717 reg
[insn
->reg
].type
= REG_S64
;
1718 next_pc
+= sizeof(struct cast_op
);
1721 case FILTER_OP_CAST_DOUBLE_TO_S64
:
1723 struct cast_op
*insn
= (struct cast_op
*) pc
;
1725 reg
[insn
->reg
].type
= REG_S64
;
1726 next_pc
+= sizeof(struct cast_op
);
1729 case FILTER_OP_CAST_NOP
:
1731 next_pc
+= sizeof(struct cast_op
);
1743 int apply_field_reloc(struct ltt_event
*event
,
1744 struct bytecode_runtime
*runtime
,
1745 uint32_t runtime_len
,
1746 uint32_t reloc_offset
,
1747 const char *field_name
)
1749 const struct lttng_event_desc
*desc
;
1750 const struct lttng_event_field
*fields
, *field
= NULL
;
1751 unsigned int nr_fields
, i
;
1752 struct field_ref
*field_ref
;
1754 uint32_t field_offset
= 0;
1756 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1758 /* Ensure that the reloc is within the code */
1759 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1762 /* Lookup event by name */
1766 fields
= desc
->fields
;
1769 nr_fields
= desc
->nr_fields
;
1770 for (i
= 0; i
< nr_fields
; i
++) {
1771 if (!strcmp(fields
[i
].name
, field_name
)) {
1775 /* compute field offset */
1776 switch (fields
[i
].type
.atype
) {
1779 field_offset
+= sizeof(int64_t);
1782 case atype_sequence
:
1783 field_offset
+= sizeof(unsigned long);
1784 field_offset
+= sizeof(void *);
1787 field_offset
+= sizeof(void *);
1790 field_offset
+= sizeof(double);
1799 /* Check if field offset is too large for 16-bit offset */
1800 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1804 op
= (struct load_op
*) &runtime
->data
[reloc_offset
];
1805 field_ref
= (struct field_ref
*) op
->data
;
1806 switch (field
->type
.atype
) {
1809 op
->op
= FILTER_OP_LOAD_FIELD_REF_S64
;
1812 case atype_sequence
:
1813 op
->op
= FILTER_OP_LOAD_FIELD_REF_SEQUENCE
;
1816 op
->op
= FILTER_OP_LOAD_FIELD_REF_STRING
;
1819 op
->op
= FILTER_OP_LOAD_FIELD_REF_DOUBLE
;
1825 field_ref
->offset
= (uint16_t) field_offset
;
1830 * Take a bytecode with reloc table and link it to an event to create a
1834 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1835 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1837 int ret
, offset
, next_offset
;
1838 struct bytecode_runtime
*runtime
= NULL
;
1839 size_t runtime_alloc_len
;
1841 if (!filter_bytecode
)
1843 /* Even is not connected to any description */
1846 /* Bytecode already linked */
1847 if (event
->filter
|| event
->filter_data
)
1850 dbg_printf("Linking\n");
1852 /* We don't need the reloc table in the runtime */
1853 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
1854 runtime
= zmalloc(runtime_alloc_len
);
1859 runtime
->len
= filter_bytecode
->reloc_offset
;
1860 /* copy original bytecode */
1861 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
1863 * apply relocs. Those are a uint16_t (offset in bytecode)
1864 * followed by a string (field name).
1866 for (offset
= filter_bytecode
->reloc_offset
;
1867 offset
< filter_bytecode
->len
;
1868 offset
= next_offset
) {
1869 uint16_t reloc_offset
=
1870 *(uint16_t *) &filter_bytecode
->data
[offset
];
1871 const char *field_name
=
1872 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
1874 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1878 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1880 /* Validate bytecode */
1881 ret
= lttng_filter_validate_bytecode(runtime
);
1885 /* Specialize bytecode */
1886 ret
= lttng_filter_specialize_bytecode(runtime
);
1890 event
->filter_data
= runtime
;
1891 event
->filter
= lttng_filter_interpret_bytecode
;
1895 event
->filter
= lttng_filter_false
;
1900 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1901 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1905 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1907 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1912 * Link bytecode to all events for a wildcard. Skips events that already
1913 * have a bytecode linked.
1914 * We do not set each event's filter_bytecode field, because they do not
1915 * own the filter_bytecode: the wildcard owns it.
1917 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1919 struct ltt_event
*event
;
1922 if (!wildcard
->filter_bytecode
)
1925 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1928 ret
= _lttng_filter_event_link_bytecode(event
,
1929 wildcard
->filter_bytecode
);
1931 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1939 * Need to attach filter to an event before starting tracing for the
1940 * session. We own the filter_bytecode if we return success.
1942 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1943 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1945 if (event
->chan
->session
->been_active
)
1947 if (event
->filter_bytecode
)
1949 event
->filter_bytecode
= filter_bytecode
;
1954 * Need to attach filter to a wildcard before starting tracing for the
1955 * session. We own the filter_bytecode if we return success.
1957 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1958 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1960 if (wildcard
->chan
->session
->been_active
)
1962 if (wildcard
->filter_bytecode
)
1964 wildcard
->filter_bytecode
= filter_bytecode
;