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 reg
[insn
->reg
].type
= REG_STRING
;
700 reg
[insn
->reg
].seq_len
= UINT_MAX
;
701 reg
[insn
->reg
].literal
= 0;
702 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
703 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
707 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE
):
709 struct load_op
*insn
= (struct load_op
*) pc
;
710 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
712 dbg_printf("load field ref offset %u type sequence\n",
714 reg
[insn
->reg
].seq_len
=
715 *(unsigned long *) &filter_stack_data
[ref
->offset
];
717 *(const char **) (&filter_stack_data
[ref
->offset
718 + sizeof(unsigned long)]);
719 reg
[insn
->reg
].type
= REG_STRING
;
720 reg
[insn
->reg
].literal
= 0;
721 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
725 OP(FILTER_OP_LOAD_FIELD_REF_S64
):
727 struct load_op
*insn
= (struct load_op
*) pc
;
728 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
730 dbg_printf("load field ref offset %u type s64\n",
732 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
733 sizeof(struct literal_numeric
));
734 reg
[insn
->reg
].type
= REG_S64
;
735 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
736 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
740 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE
):
742 struct load_op
*insn
= (struct load_op
*) pc
;
743 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
745 dbg_printf("load field ref offset %u type double\n",
747 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
748 sizeof(struct literal_double
));
749 reg
[insn
->reg
].type
= REG_DOUBLE
;
750 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
751 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
755 OP(FILTER_OP_LOAD_STRING
):
757 struct load_op
*insn
= (struct load_op
*) pc
;
759 dbg_printf("load string %s\n", insn
->data
);
760 reg
[insn
->reg
].str
= insn
->data
;
761 reg
[insn
->reg
].type
= REG_STRING
;
762 reg
[insn
->reg
].seq_len
= UINT_MAX
;
763 reg
[insn
->reg
].literal
= 1;
764 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
768 OP(FILTER_OP_LOAD_S64
):
770 struct load_op
*insn
= (struct load_op
*) pc
;
772 memcpy(®
[insn
->reg
].v
, insn
->data
,
773 sizeof(struct literal_numeric
));
774 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
775 reg
[insn
->reg
].type
= REG_S64
;
776 next_pc
+= sizeof(struct load_op
)
777 + sizeof(struct literal_numeric
);
781 OP(FILTER_OP_LOAD_DOUBLE
):
783 struct load_op
*insn
= (struct load_op
*) pc
;
785 memcpy(®
[insn
->reg
].d
, insn
->data
,
786 sizeof(struct literal_double
));
787 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
788 reg
[insn
->reg
].type
= REG_DOUBLE
;
789 next_pc
+= sizeof(struct load_op
)
790 + sizeof(struct literal_double
);
795 OP(FILTER_OP_CAST_TO_S64
):
796 ERR("unsupported non-specialized bytecode op %u\n",
797 (unsigned int) *(filter_opcode_t
*) pc
);
801 OP(FILTER_OP_CAST_DOUBLE_TO_S64
):
803 struct cast_op
*insn
= (struct cast_op
*) pc
;
805 reg
[insn
->reg
].v
= (int64_t) reg
[insn
->reg
].d
;
806 reg
[insn
->reg
].type
= REG_S64
;
807 next_pc
+= sizeof(struct cast_op
);
811 OP(FILTER_OP_CAST_NOP
):
813 next_pc
+= sizeof(struct cast_op
);
819 /* return 0 (discard) on error */
831 int bin_op_compare_check(struct vreg reg
[NR_REG
], const char *str
)
833 switch (reg
[REG_R0
].type
) {
838 switch (reg
[REG_R1
].type
) {
851 switch (reg
[REG_R1
].type
) {
870 ERR("type mismatch for '%s' binary operator\n", str
);
875 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
877 void *pc
, *next_pc
, *start_pc
;
879 struct vreg reg
[NR_REG
];
882 for (i
= 0; i
< NR_REG
; i
++) {
883 reg
[i
].type
= REG_TYPE_UNKNOWN
;
887 start_pc
= &bytecode
->data
[0];
888 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
890 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
891 ERR("filter bytecode overflow\n");
895 dbg_printf("Validating op %s (%u)\n",
896 print_op((unsigned int) *(filter_opcode_t
*) pc
),
897 (unsigned int) *(filter_opcode_t
*) pc
);
898 switch (*(filter_opcode_t
*) pc
) {
899 case FILTER_OP_UNKNOWN
:
901 ERR("unknown bytecode op %u\n",
902 (unsigned int) *(filter_opcode_t
*) pc
);
906 case FILTER_OP_RETURN
:
915 case FILTER_OP_MINUS
:
916 case FILTER_OP_RSHIFT
:
917 case FILTER_OP_LSHIFT
:
918 case FILTER_OP_BIN_AND
:
919 case FILTER_OP_BIN_OR
:
920 case FILTER_OP_BIN_XOR
:
921 ERR("unsupported bytecode op %u\n",
922 (unsigned int) *(filter_opcode_t
*) pc
);
928 ret
= bin_op_compare_check(reg
, "==");
931 reg
[REG_R0
].type
= REG_S64
;
932 next_pc
+= sizeof(struct binary_op
);
937 ret
= bin_op_compare_check(reg
, "!=");
940 reg
[REG_R0
].type
= REG_S64
;
941 next_pc
+= sizeof(struct binary_op
);
946 ret
= bin_op_compare_check(reg
, ">");
949 reg
[REG_R0
].type
= REG_S64
;
950 next_pc
+= sizeof(struct binary_op
);
955 ret
= bin_op_compare_check(reg
, "<");
958 reg
[REG_R0
].type
= REG_S64
;
959 next_pc
+= sizeof(struct binary_op
);
964 ret
= bin_op_compare_check(reg
, ">=");
967 reg
[REG_R0
].type
= REG_S64
;
968 next_pc
+= sizeof(struct binary_op
);
973 ret
= bin_op_compare_check(reg
, "<=");
976 reg
[REG_R0
].type
= REG_S64
;
977 next_pc
+= sizeof(struct binary_op
);
981 case FILTER_OP_EQ_STRING
:
982 case FILTER_OP_NE_STRING
:
983 case FILTER_OP_GT_STRING
:
984 case FILTER_OP_LT_STRING
:
985 case FILTER_OP_GE_STRING
:
986 case FILTER_OP_LE_STRING
:
988 if (reg
[REG_R0
].type
!= REG_STRING
989 || reg
[REG_R1
].type
!= REG_STRING
) {
990 ERR("Unexpected register type for string comparator\n");
994 reg
[REG_R0
].type
= REG_S64
;
995 next_pc
+= sizeof(struct binary_op
);
999 case FILTER_OP_EQ_S64
:
1000 case FILTER_OP_NE_S64
:
1001 case FILTER_OP_GT_S64
:
1002 case FILTER_OP_LT_S64
:
1003 case FILTER_OP_GE_S64
:
1004 case FILTER_OP_LE_S64
:
1006 if (reg
[REG_R0
].type
!= REG_S64
1007 || reg
[REG_R1
].type
!= REG_S64
) {
1008 ERR("Unexpected register type for s64 comparator\n");
1012 reg
[REG_R0
].type
= REG_S64
;
1013 next_pc
+= sizeof(struct binary_op
);
1017 case FILTER_OP_EQ_DOUBLE
:
1018 case FILTER_OP_NE_DOUBLE
:
1019 case FILTER_OP_GT_DOUBLE
:
1020 case FILTER_OP_LT_DOUBLE
:
1021 case FILTER_OP_GE_DOUBLE
:
1022 case FILTER_OP_LE_DOUBLE
:
1024 if ((reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R0
].type
!= REG_S64
)
1025 || (reg
[REG_R1
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_S64
)) {
1026 ERR("Unexpected register type for double comparator\n");
1030 if (reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_DOUBLE
) {
1031 ERR("Double operator should have at least one double register\n");
1035 reg
[REG_R0
].type
= REG_DOUBLE
;
1036 next_pc
+= sizeof(struct binary_op
);
1041 case FILTER_OP_UNARY_PLUS
:
1042 case FILTER_OP_UNARY_MINUS
:
1043 case FILTER_OP_UNARY_NOT
:
1045 struct unary_op
*insn
= (struct unary_op
*) pc
;
1047 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1048 ERR("invalid register %u\n",
1049 (unsigned int) insn
->reg
);
1053 switch (reg
[insn
->reg
].type
) {
1055 ERR("unknown register type\n");
1060 ERR("Unary op can only be applied to numeric or floating point registers\n");
1068 next_pc
+= sizeof(struct unary_op
);
1072 case FILTER_OP_UNARY_PLUS_S64
:
1073 case FILTER_OP_UNARY_MINUS_S64
:
1074 case FILTER_OP_UNARY_NOT_S64
:
1076 struct unary_op
*insn
= (struct unary_op
*) pc
;
1078 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1079 ERR("invalid register %u\n",
1080 (unsigned int) insn
->reg
);
1084 if (reg
[insn
->reg
].type
!= REG_S64
) {
1085 ERR("Invalid register type\n");
1089 next_pc
+= sizeof(struct unary_op
);
1093 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1094 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1095 case FILTER_OP_UNARY_NOT_DOUBLE
:
1097 struct unary_op
*insn
= (struct unary_op
*) pc
;
1099 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1100 ERR("invalid register %u\n",
1101 (unsigned int) insn
->reg
);
1105 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
1106 ERR("Invalid register type\n");
1110 next_pc
+= sizeof(struct unary_op
);
1118 struct logical_op
*insn
= (struct logical_op
*) pc
;
1120 if (reg
[REG_R0
].type
!= REG_S64
) {
1121 ERR("Logical comparator expects S64 register\n");
1126 dbg_printf("Validate jumping to bytecode offset %u\n",
1127 (unsigned int) insn
->skip_offset
);
1128 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
1129 ERR("Loops are not allowed in bytecode\n");
1133 next_pc
+= sizeof(struct logical_op
);
1138 case FILTER_OP_LOAD_FIELD_REF
:
1140 ERR("Unknown field ref type\n");
1144 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1145 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1147 struct load_op
*insn
= (struct load_op
*) pc
;
1148 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1150 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1151 ERR("invalid register %u\n",
1152 (unsigned int) insn
->reg
);
1156 dbg_printf("Validate load field ref offset %u type string\n",
1158 reg
[insn
->reg
].type
= REG_STRING
;
1159 reg
[insn
->reg
].literal
= 0;
1160 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1163 case FILTER_OP_LOAD_FIELD_REF_S64
:
1165 struct load_op
*insn
= (struct load_op
*) pc
;
1166 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1168 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1169 ERR("invalid register %u\n",
1170 (unsigned int) insn
->reg
);
1174 dbg_printf("Validate load field ref offset %u type s64\n",
1176 reg
[insn
->reg
].type
= REG_S64
;
1177 reg
[insn
->reg
].literal
= 0;
1178 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1181 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1183 struct load_op
*insn
= (struct load_op
*) pc
;
1184 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1186 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1187 ERR("invalid register %u\n",
1188 (unsigned int) insn
->reg
);
1192 dbg_printf("Validate load field ref offset %u type double\n",
1194 reg
[insn
->reg
].type
= REG_DOUBLE
;
1195 reg
[insn
->reg
].literal
= 0;
1196 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1200 case FILTER_OP_LOAD_STRING
:
1202 struct load_op
*insn
= (struct load_op
*) pc
;
1204 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1205 ERR("invalid register %u\n",
1206 (unsigned int) insn
->reg
);
1210 reg
[insn
->reg
].type
= REG_STRING
;
1211 reg
[insn
->reg
].literal
= 1;
1212 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1216 case FILTER_OP_LOAD_S64
:
1218 struct load_op
*insn
= (struct load_op
*) pc
;
1220 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1221 ERR("invalid register %u\n",
1222 (unsigned int) insn
->reg
);
1226 reg
[insn
->reg
].type
= REG_S64
;
1227 reg
[insn
->reg
].literal
= 1;
1228 next_pc
+= sizeof(struct load_op
)
1229 + sizeof(struct literal_numeric
);
1233 case FILTER_OP_LOAD_DOUBLE
:
1235 struct load_op
*insn
= (struct load_op
*) pc
;
1237 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1238 ERR("invalid register %u\n",
1239 (unsigned int) insn
->reg
);
1243 reg
[insn
->reg
].type
= REG_DOUBLE
;
1244 reg
[insn
->reg
].literal
= 1;
1245 next_pc
+= sizeof(struct load_op
)
1246 + sizeof(struct literal_double
);
1250 case FILTER_OP_CAST_TO_S64
:
1251 case FILTER_OP_CAST_DOUBLE_TO_S64
:
1253 struct cast_op
*insn
= (struct cast_op
*) pc
;
1255 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1256 ERR("invalid register %u\n",
1257 (unsigned int) insn
->reg
);
1261 switch (reg
[insn
->reg
].type
) {
1263 ERR("unknown register type\n");
1268 ERR("Cast op can only be applied to numeric or floating point registers\n");
1276 if (insn
->op
== FILTER_OP_CAST_DOUBLE_TO_S64
) {
1277 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
1278 ERR("Cast expects double\n");
1283 reg
[insn
->reg
].type
= REG_S64
;
1284 next_pc
+= sizeof(struct cast_op
);
1287 case FILTER_OP_CAST_NOP
:
1289 next_pc
+= sizeof(struct cast_op
);
1300 int lttng_filter_specialize_bytecode(struct bytecode_runtime
*bytecode
)
1302 void *pc
, *next_pc
, *start_pc
;
1304 struct vreg reg
[NR_REG
];
1307 for (i
= 0; i
< NR_REG
; i
++) {
1308 reg
[i
].type
= REG_TYPE_UNKNOWN
;
1312 start_pc
= &bytecode
->data
[0];
1313 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1315 switch (*(filter_opcode_t
*) pc
) {
1316 case FILTER_OP_UNKNOWN
:
1318 ERR("unknown bytecode op %u\n",
1319 (unsigned int) *(filter_opcode_t
*) pc
);
1323 case FILTER_OP_RETURN
:
1331 case FILTER_OP_PLUS
:
1332 case FILTER_OP_MINUS
:
1333 case FILTER_OP_RSHIFT
:
1334 case FILTER_OP_LSHIFT
:
1335 case FILTER_OP_BIN_AND
:
1336 case FILTER_OP_BIN_OR
:
1337 case FILTER_OP_BIN_XOR
:
1338 ERR("unsupported bytecode op %u\n",
1339 (unsigned int) *(filter_opcode_t
*) pc
);
1345 struct binary_op
*insn
= (struct binary_op
*) pc
;
1347 switch(reg
[REG_R0
].type
) {
1349 ERR("unknown register type\n");
1354 insn
->op
= FILTER_OP_EQ_STRING
;
1357 if (reg
[REG_R1
].type
== REG_S64
)
1358 insn
->op
= FILTER_OP_EQ_S64
;
1360 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1363 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1366 reg
[REG_R0
].type
= REG_S64
;
1367 next_pc
+= sizeof(struct binary_op
);
1373 struct binary_op
*insn
= (struct binary_op
*) pc
;
1375 switch(reg
[REG_R0
].type
) {
1377 ERR("unknown register type\n");
1382 insn
->op
= FILTER_OP_NE_STRING
;
1385 if (reg
[REG_R1
].type
== REG_S64
)
1386 insn
->op
= FILTER_OP_NE_S64
;
1388 insn
->op
= FILTER_OP_NE_DOUBLE
;
1391 insn
->op
= FILTER_OP_NE_DOUBLE
;
1394 reg
[REG_R0
].type
= REG_S64
;
1395 next_pc
+= sizeof(struct binary_op
);
1401 struct binary_op
*insn
= (struct binary_op
*) pc
;
1403 switch(reg
[REG_R0
].type
) {
1405 ERR("unknown register type\n");
1410 insn
->op
= FILTER_OP_GT_STRING
;
1413 if (reg
[REG_R1
].type
== REG_S64
)
1414 insn
->op
= FILTER_OP_GT_S64
;
1416 insn
->op
= FILTER_OP_GT_DOUBLE
;
1419 insn
->op
= FILTER_OP_GT_DOUBLE
;
1422 reg
[REG_R0
].type
= REG_S64
;
1423 next_pc
+= sizeof(struct binary_op
);
1429 struct binary_op
*insn
= (struct binary_op
*) pc
;
1431 switch(reg
[REG_R0
].type
) {
1433 ERR("unknown register type\n");
1438 insn
->op
= FILTER_OP_LT_STRING
;
1441 if (reg
[REG_R1
].type
== REG_S64
)
1442 insn
->op
= FILTER_OP_LT_S64
;
1444 insn
->op
= FILTER_OP_LT_DOUBLE
;
1447 insn
->op
= FILTER_OP_LT_DOUBLE
;
1450 reg
[REG_R0
].type
= REG_S64
;
1451 next_pc
+= sizeof(struct binary_op
);
1457 struct binary_op
*insn
= (struct binary_op
*) pc
;
1459 switch(reg
[REG_R0
].type
) {
1461 ERR("unknown register type\n");
1466 insn
->op
= FILTER_OP_GE_STRING
;
1469 if (reg
[REG_R1
].type
== REG_S64
)
1470 insn
->op
= FILTER_OP_GE_S64
;
1472 insn
->op
= FILTER_OP_GE_DOUBLE
;
1475 insn
->op
= FILTER_OP_GE_DOUBLE
;
1478 reg
[REG_R0
].type
= REG_S64
;
1479 next_pc
+= sizeof(struct binary_op
);
1484 struct binary_op
*insn
= (struct binary_op
*) pc
;
1486 switch(reg
[REG_R0
].type
) {
1488 ERR("unknown register type\n");
1493 insn
->op
= FILTER_OP_LE_STRING
;
1496 if (reg
[REG_R1
].type
== REG_S64
)
1497 insn
->op
= FILTER_OP_LE_S64
;
1499 insn
->op
= FILTER_OP_LE_DOUBLE
;
1502 insn
->op
= FILTER_OP_LE_DOUBLE
;
1505 reg
[REG_R0
].type
= REG_S64
;
1506 next_pc
+= sizeof(struct binary_op
);
1510 case FILTER_OP_EQ_STRING
:
1511 case FILTER_OP_NE_STRING
:
1512 case FILTER_OP_GT_STRING
:
1513 case FILTER_OP_LT_STRING
:
1514 case FILTER_OP_GE_STRING
:
1515 case FILTER_OP_LE_STRING
:
1516 case FILTER_OP_EQ_S64
:
1517 case FILTER_OP_NE_S64
:
1518 case FILTER_OP_GT_S64
:
1519 case FILTER_OP_LT_S64
:
1520 case FILTER_OP_GE_S64
:
1521 case FILTER_OP_LE_S64
:
1522 case FILTER_OP_EQ_DOUBLE
:
1523 case FILTER_OP_NE_DOUBLE
:
1524 case FILTER_OP_GT_DOUBLE
:
1525 case FILTER_OP_LT_DOUBLE
:
1526 case FILTER_OP_GE_DOUBLE
:
1527 case FILTER_OP_LE_DOUBLE
:
1529 reg
[REG_R0
].type
= REG_S64
;
1530 next_pc
+= sizeof(struct binary_op
);
1535 case FILTER_OP_UNARY_PLUS
:
1537 struct unary_op
*insn
= (struct unary_op
*) pc
;
1539 switch(reg
[insn
->reg
].type
) {
1541 ERR("unknown register type\n");
1546 insn
->op
= FILTER_OP_UNARY_PLUS_S64
;
1549 insn
->op
= FILTER_OP_UNARY_PLUS_DOUBLE
;
1552 next_pc
+= sizeof(struct unary_op
);
1556 case FILTER_OP_UNARY_MINUS
:
1558 struct unary_op
*insn
= (struct unary_op
*) pc
;
1560 switch(reg
[insn
->reg
].type
) {
1562 ERR("unknown register type\n");
1567 insn
->op
= FILTER_OP_UNARY_MINUS_S64
;
1570 insn
->op
= FILTER_OP_UNARY_MINUS_DOUBLE
;
1573 next_pc
+= sizeof(struct unary_op
);
1577 case FILTER_OP_UNARY_NOT
:
1579 struct unary_op
*insn
= (struct unary_op
*) pc
;
1581 switch(reg
[insn
->reg
].type
) {
1583 ERR("unknown register type\n");
1588 insn
->op
= FILTER_OP_UNARY_NOT_S64
;
1591 insn
->op
= FILTER_OP_UNARY_NOT_DOUBLE
;
1594 next_pc
+= sizeof(struct unary_op
);
1598 case FILTER_OP_UNARY_PLUS_S64
:
1599 case FILTER_OP_UNARY_MINUS_S64
:
1600 case FILTER_OP_UNARY_NOT_S64
:
1601 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1602 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1603 case FILTER_OP_UNARY_NOT_DOUBLE
:
1605 next_pc
+= sizeof(struct unary_op
);
1613 next_pc
+= sizeof(struct logical_op
);
1618 case FILTER_OP_LOAD_FIELD_REF
:
1620 ERR("Unknown field ref type\n");
1624 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1625 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1627 struct load_op
*insn
= (struct load_op
*) pc
;
1629 reg
[insn
->reg
].type
= REG_STRING
;
1630 reg
[insn
->reg
].literal
= 0;
1631 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1634 case FILTER_OP_LOAD_FIELD_REF_S64
:
1636 struct load_op
*insn
= (struct load_op
*) pc
;
1638 reg
[insn
->reg
].type
= REG_S64
;
1639 reg
[insn
->reg
].literal
= 0;
1640 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1643 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1645 struct load_op
*insn
= (struct load_op
*) pc
;
1647 reg
[insn
->reg
].type
= REG_DOUBLE
;
1648 reg
[insn
->reg
].literal
= 0;
1649 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1653 case FILTER_OP_LOAD_STRING
:
1655 struct load_op
*insn
= (struct load_op
*) pc
;
1657 reg
[insn
->reg
].type
= REG_STRING
;
1658 reg
[insn
->reg
].literal
= 1;
1659 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1663 case FILTER_OP_LOAD_S64
:
1665 struct load_op
*insn
= (struct load_op
*) pc
;
1667 reg
[insn
->reg
].type
= REG_S64
;
1668 reg
[insn
->reg
].literal
= 1;
1669 next_pc
+= sizeof(struct load_op
)
1670 + sizeof(struct literal_numeric
);
1674 case FILTER_OP_LOAD_DOUBLE
:
1676 struct load_op
*insn
= (struct load_op
*) pc
;
1678 reg
[insn
->reg
].type
= REG_DOUBLE
;
1679 reg
[insn
->reg
].literal
= 1;
1680 next_pc
+= sizeof(struct load_op
)
1681 + sizeof(struct literal_double
);
1686 case FILTER_OP_CAST_TO_S64
:
1688 struct cast_op
*insn
= (struct cast_op
*) pc
;
1690 switch (reg
[insn
->reg
].type
) {
1692 ERR("unknown register type\n");
1697 ERR("Cast op can only be applied to numeric or floating point registers\n");
1701 insn
->op
= FILTER_OP_CAST_NOP
;
1704 insn
->op
= FILTER_OP_CAST_DOUBLE_TO_S64
;
1707 reg
[insn
->reg
].type
= REG_S64
;
1708 next_pc
+= sizeof(struct cast_op
);
1711 case FILTER_OP_CAST_DOUBLE_TO_S64
:
1713 struct cast_op
*insn
= (struct cast_op
*) pc
;
1715 reg
[insn
->reg
].type
= REG_S64
;
1716 next_pc
+= sizeof(struct cast_op
);
1719 case FILTER_OP_CAST_NOP
:
1721 next_pc
+= sizeof(struct cast_op
);
1733 int apply_field_reloc(struct ltt_event
*event
,
1734 struct bytecode_runtime
*runtime
,
1735 uint32_t runtime_len
,
1736 uint32_t reloc_offset
,
1737 const char *field_name
)
1739 const struct lttng_event_desc
*desc
;
1740 const struct lttng_event_field
*fields
, *field
= NULL
;
1741 unsigned int nr_fields
, i
;
1742 struct field_ref
*field_ref
;
1744 uint32_t field_offset
= 0;
1746 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1748 /* Ensure that the reloc is within the code */
1749 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1752 /* Lookup event by name */
1756 fields
= desc
->fields
;
1759 nr_fields
= desc
->nr_fields
;
1760 for (i
= 0; i
< nr_fields
; i
++) {
1761 if (!strcmp(fields
[i
].name
, field_name
)) {
1765 /* compute field offset */
1766 switch (fields
[i
].type
.atype
) {
1769 field_offset
+= sizeof(int64_t);
1772 case atype_sequence
:
1773 field_offset
+= sizeof(unsigned long);
1774 field_offset
+= sizeof(void *);
1777 field_offset
+= sizeof(void *);
1780 field_offset
+= sizeof(double);
1789 /* Check if field offset is too large for 16-bit offset */
1790 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1794 op
= (struct load_op
*) &runtime
->data
[reloc_offset
];
1795 field_ref
= (struct field_ref
*) op
->data
;
1796 switch (field
->type
.atype
) {
1799 op
->op
= FILTER_OP_LOAD_FIELD_REF_S64
;
1802 case atype_sequence
:
1803 op
->op
= FILTER_OP_LOAD_FIELD_REF_SEQUENCE
;
1806 op
->op
= FILTER_OP_LOAD_FIELD_REF_STRING
;
1809 op
->op
= FILTER_OP_LOAD_FIELD_REF_DOUBLE
;
1815 field_ref
->offset
= (uint16_t) field_offset
;
1820 * Take a bytecode with reloc table and link it to an event to create a
1824 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1825 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1827 int ret
, offset
, next_offset
;
1828 struct bytecode_runtime
*runtime
= NULL
;
1829 size_t runtime_alloc_len
;
1831 if (!filter_bytecode
)
1833 /* Even is not connected to any description */
1836 /* Bytecode already linked */
1837 if (event
->filter
|| event
->filter_data
)
1840 dbg_printf("Linking\n");
1842 /* We don't need the reloc table in the runtime */
1843 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
1844 runtime
= zmalloc(runtime_alloc_len
);
1849 runtime
->len
= filter_bytecode
->reloc_offset
;
1850 /* copy original bytecode */
1851 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
1853 * apply relocs. Those are a uint16_t (offset in bytecode)
1854 * followed by a string (field name).
1856 for (offset
= filter_bytecode
->reloc_offset
;
1857 offset
< filter_bytecode
->len
;
1858 offset
= next_offset
) {
1859 uint16_t reloc_offset
=
1860 *(uint16_t *) &filter_bytecode
->data
[offset
];
1861 const char *field_name
=
1862 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
1864 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1868 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1870 /* Validate bytecode */
1871 ret
= lttng_filter_validate_bytecode(runtime
);
1875 /* Specialize bytecode */
1876 ret
= lttng_filter_specialize_bytecode(runtime
);
1880 event
->filter_data
= runtime
;
1881 event
->filter
= lttng_filter_interpret_bytecode
;
1885 event
->filter
= lttng_filter_false
;
1890 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1891 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1895 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1897 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1902 * Link bytecode to all events for a wildcard. Skips events that already
1903 * have a bytecode linked.
1904 * We do not set each event's filter_bytecode field, because they do not
1905 * own the filter_bytecode: the wildcard owns it.
1907 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1909 struct ltt_event
*event
;
1912 if (!wildcard
->filter_bytecode
)
1915 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1918 ret
= _lttng_filter_event_link_bytecode(event
,
1919 wildcard
->filter_bytecode
);
1921 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1929 * Need to attach filter to an event before starting tracing for the
1930 * session. We own the filter_bytecode if we return success.
1932 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1933 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1935 if (event
->chan
->session
->been_active
)
1937 if (event
->filter_bytecode
)
1939 event
->filter_bytecode
= filter_bytecode
;
1944 * Need to attach filter to a wildcard before starting tracing for the
1945 * session. We own the filter_bytecode if we return success.
1947 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1948 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1950 if (wildcard
->chan
->session
->been_active
)
1952 if (wildcard
->filter_bytecode
)
1954 wildcard
->filter_bytecode
= filter_bytecode
;