4 * LTTng UST filter code.
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <lttng/ust-events.h>
32 #include <usterr-signal-safe.h>
33 #include "filter-bytecode.h"
38 #define min_t(type, a, b) \
39 ((type) (a) < (type) (b) ? (type) (a) : (type) (b))
43 #define likely(x) __builtin_expect(!!(x), 1)
47 #define unlikely(x) __builtin_expect(!!(x), 0)
51 #define dbg_printf(fmt, args...) printf("[debug bytecode] " fmt, ## args)
53 #define dbg_printf(fmt, args...) \
55 /* do nothing but check printf format */ \
57 printf("[debug bytecode] " fmt, ## args); \
62 struct bytecode_runtime
{
74 /* Validation registers */
77 int literal
; /* is string literal ? */
80 /* Execution registers */
88 int literal
; /* is string literal ? */
91 static const char *opnames
[] = {
92 [ FILTER_OP_UNKNOWN
] = "UNKNOWN",
94 [ FILTER_OP_RETURN
] = "RETURN",
97 [ FILTER_OP_MUL
] = "MUL",
98 [ FILTER_OP_DIV
] = "DIV",
99 [ FILTER_OP_MOD
] = "MOD",
100 [ FILTER_OP_PLUS
] = "PLUS",
101 [ FILTER_OP_MINUS
] = "MINUS",
102 [ FILTER_OP_RSHIFT
] = "RSHIFT",
103 [ FILTER_OP_LSHIFT
] = "LSHIFT",
104 [ FILTER_OP_BIN_AND
] = "BIN_AND",
105 [ FILTER_OP_BIN_OR
] = "BIN_OR",
106 [ FILTER_OP_BIN_XOR
] = "BIN_XOR",
108 /* binary comparators */
109 [ FILTER_OP_EQ
] = "EQ",
110 [ FILTER_OP_NE
] = "NE",
111 [ FILTER_OP_GT
] = "GT",
112 [ FILTER_OP_LT
] = "LT",
113 [ FILTER_OP_GE
] = "GE",
114 [ FILTER_OP_LE
] = "LE",
116 /* string binary comparators */
117 [ FILTER_OP_EQ_STRING
] = "EQ_STRING",
118 [ FILTER_OP_NE_STRING
] = "NE_STRING",
119 [ FILTER_OP_GT_STRING
] = "GT_STRING",
120 [ FILTER_OP_LT_STRING
] = "LT_STRING",
121 [ FILTER_OP_GE_STRING
] = "GE_STRING",
122 [ FILTER_OP_LE_STRING
] = "LE_STRING",
124 /* s64 binary comparators */
125 [ FILTER_OP_EQ_S64
] = "EQ_S64",
126 [ FILTER_OP_NE_S64
] = "NE_S64",
127 [ FILTER_OP_GT_S64
] = "GT_S64",
128 [ FILTER_OP_LT_S64
] = "LT_S64",
129 [ FILTER_OP_GE_S64
] = "GE_S64",
130 [ FILTER_OP_LE_S64
] = "LE_S64",
132 /* double binary comparators */
133 [ FILTER_OP_EQ_DOUBLE
] = "EQ_DOUBLE",
134 [ FILTER_OP_NE_DOUBLE
] = "NE_DOUBLE",
135 [ FILTER_OP_GT_DOUBLE
] = "GT_DOUBLE",
136 [ FILTER_OP_LT_DOUBLE
] = "LT_DOUBLE",
137 [ FILTER_OP_GE_DOUBLE
] = "GE_DOUBLE",
138 [ FILTER_OP_LE_DOUBLE
] = "LE_DOUBLE",
142 [ FILTER_OP_UNARY_PLUS
] = "UNARY_PLUS",
143 [ FILTER_OP_UNARY_MINUS
] = "UNARY_MINUS",
144 [ FILTER_OP_UNARY_NOT
] = "UNARY_NOT",
145 [ FILTER_OP_UNARY_PLUS_S64
] = "UNARY_PLUS_S64",
146 [ FILTER_OP_UNARY_MINUS_S64
] = "UNARY_MINUS_S64",
147 [ FILTER_OP_UNARY_NOT_S64
] = "UNARY_NOT_S64",
148 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = "UNARY_PLUS_DOUBLE",
149 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = "UNARY_MINUS_DOUBLE",
150 [ FILTER_OP_UNARY_NOT_DOUBLE
] = "UNARY_NOT_DOUBLE",
153 [ FILTER_OP_AND
] = "AND",
154 [ FILTER_OP_OR
] = "OR",
155 [ FILTER_OP_AND_S64
] = "AND_S64",
156 [ FILTER_OP_OR_S64
] = "OR_S64",
157 [ FILTER_OP_AND_DOUBLE
] = "AND_DOUBLE",
158 [ FILTER_OP_OR_DOUBLE
] = "OR_DOUBLE",
161 [ FILTER_OP_LOAD_FIELD_REF
] = "LOAD_FIELD_REF",
162 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = "LOAD_FIELD_REF_STRING",
163 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = "LOAD_FIELD_REF_SEQUENCE",
164 [ FILTER_OP_LOAD_FIELD_REF_S64
] = "LOAD_FIELD_REF_S64",
165 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = "LOAD_FIELD_REF_DOUBLE",
167 [ FILTER_OP_LOAD_STRING
] = "LOAD_STRING",
168 [ FILTER_OP_LOAD_S64
] = "LOAD_S64",
169 [ FILTER_OP_LOAD_DOUBLE
] = "LOAD_DOUBLE",
173 const char *print_op(enum filter_op op
)
175 if (op
>= NR_FILTER_OPS
)
182 * -1: wildcard found.
183 * -2: unknown escape char.
188 int parse_char(const char **p
)
208 int reg_strcmp(struct reg reg
[NR_REG
], const char *cmp_type
)
210 const char *p
= reg
[REG_R0
].str
, *q
= reg
[REG_R1
].str
;
217 if (unlikely(p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')) {
218 if (q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')
224 if (unlikely(q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')) {
225 if (p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')
231 if (reg
[REG_R0
].literal
) {
232 ret
= parse_char(&p
);
235 } else if (ret
== -2) {
238 /* else compare both char */
240 if (reg
[REG_R1
].literal
) {
241 ret
= parse_char(&q
);
244 } else if (ret
== -2) {
265 int lttng_filter_false(void *filter_data
,
266 const char *filter_stack_data
)
271 #ifdef INTERPRETER_USE_SWITCH
274 * Fallback for compilers that do not support taking address of labels.
278 start_pc = &bytecode->data[0]; \
279 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
281 dbg_printf("Executing op %s (%u)\n", \
282 print_op((unsigned int) *(filter_opcode_t *) pc), \
283 (unsigned int) *(filter_opcode_t *) pc); \
284 switch (*(filter_opcode_t *) pc) {
286 #define OP(name) case name
296 * Dispatch-table based interpreter.
300 start_pc = &bytecode->data[0]; \
301 pc = next_pc = start_pc; \
302 if (unlikely(pc - start_pc >= bytecode->len)) \
304 goto *dispatch[*(filter_opcode_t *) pc];
311 goto *dispatch[*(filter_opcode_t *) pc];
318 int lttng_filter_interpret_bytecode(void *filter_data
,
319 const char *filter_stack_data
)
321 struct bytecode_runtime
*bytecode
= filter_data
;
322 void *pc
, *next_pc
, *start_pc
;
325 struct reg reg
[NR_REG
];
326 #ifndef INTERPRETER_USE_SWITCH
327 static void *dispatch
[NR_FILTER_OPS
] = {
328 [ FILTER_OP_UNKNOWN
] = &&LABEL_FILTER_OP_UNKNOWN
,
330 [ FILTER_OP_RETURN
] = &&LABEL_FILTER_OP_RETURN
,
333 [ FILTER_OP_MUL
] = &&LABEL_FILTER_OP_MUL
,
334 [ FILTER_OP_DIV
] = &&LABEL_FILTER_OP_DIV
,
335 [ FILTER_OP_MOD
] = &&LABEL_FILTER_OP_MOD
,
336 [ FILTER_OP_PLUS
] = &&LABEL_FILTER_OP_PLUS
,
337 [ FILTER_OP_MINUS
] = &&LABEL_FILTER_OP_MINUS
,
338 [ FILTER_OP_RSHIFT
] = &&LABEL_FILTER_OP_RSHIFT
,
339 [ FILTER_OP_LSHIFT
] = &&LABEL_FILTER_OP_LSHIFT
,
340 [ FILTER_OP_BIN_AND
] = &&LABEL_FILTER_OP_BIN_AND
,
341 [ FILTER_OP_BIN_OR
] = &&LABEL_FILTER_OP_BIN_OR
,
342 [ FILTER_OP_BIN_XOR
] = &&LABEL_FILTER_OP_BIN_XOR
,
344 /* binary comparators */
345 [ FILTER_OP_EQ
] = &&LABEL_FILTER_OP_EQ
,
346 [ FILTER_OP_NE
] = &&LABEL_FILTER_OP_NE
,
347 [ FILTER_OP_GT
] = &&LABEL_FILTER_OP_GT
,
348 [ FILTER_OP_LT
] = &&LABEL_FILTER_OP_LT
,
349 [ FILTER_OP_GE
] = &&LABEL_FILTER_OP_GE
,
350 [ FILTER_OP_LE
] = &&LABEL_FILTER_OP_LE
,
352 /* string binary comparator */
353 [ FILTER_OP_EQ_STRING
] = &&LABEL_FILTER_OP_EQ_STRING
,
354 [ FILTER_OP_NE_STRING
] = &&LABEL_FILTER_OP_NE_STRING
,
355 [ FILTER_OP_GT_STRING
] = &&LABEL_FILTER_OP_GT_STRING
,
356 [ FILTER_OP_LT_STRING
] = &&LABEL_FILTER_OP_LT_STRING
,
357 [ FILTER_OP_GE_STRING
] = &&LABEL_FILTER_OP_GE_STRING
,
358 [ FILTER_OP_LE_STRING
] = &&LABEL_FILTER_OP_LE_STRING
,
360 /* s64 binary comparator */
361 [ FILTER_OP_EQ_S64
] = &&LABEL_FILTER_OP_EQ_S64
,
362 [ FILTER_OP_NE_S64
] = &&LABEL_FILTER_OP_NE_S64
,
363 [ FILTER_OP_GT_S64
] = &&LABEL_FILTER_OP_GT_S64
,
364 [ FILTER_OP_LT_S64
] = &&LABEL_FILTER_OP_LT_S64
,
365 [ FILTER_OP_GE_S64
] = &&LABEL_FILTER_OP_GE_S64
,
366 [ FILTER_OP_LE_S64
] = &&LABEL_FILTER_OP_LE_S64
,
368 /* double binary comparator */
369 [ FILTER_OP_EQ_DOUBLE
] = &&LABEL_FILTER_OP_EQ_DOUBLE
,
370 [ FILTER_OP_NE_DOUBLE
] = &&LABEL_FILTER_OP_NE_DOUBLE
,
371 [ FILTER_OP_GT_DOUBLE
] = &&LABEL_FILTER_OP_GT_DOUBLE
,
372 [ FILTER_OP_LT_DOUBLE
] = &&LABEL_FILTER_OP_LT_DOUBLE
,
373 [ FILTER_OP_GE_DOUBLE
] = &&LABEL_FILTER_OP_GE_DOUBLE
,
374 [ FILTER_OP_LE_DOUBLE
] = &&LABEL_FILTER_OP_LE_DOUBLE
,
377 [ FILTER_OP_UNARY_PLUS
] = &&LABEL_FILTER_OP_UNARY_PLUS
,
378 [ FILTER_OP_UNARY_MINUS
] = &&LABEL_FILTER_OP_UNARY_MINUS
,
379 [ FILTER_OP_UNARY_NOT
] = &&LABEL_FILTER_OP_UNARY_NOT
,
380 [ FILTER_OP_UNARY_PLUS_S64
] = &&LABEL_FILTER_OP_UNARY_PLUS_S64
,
381 [ FILTER_OP_UNARY_MINUS_S64
] = &&LABEL_FILTER_OP_UNARY_MINUS_S64
,
382 [ FILTER_OP_UNARY_NOT_S64
] = &&LABEL_FILTER_OP_UNARY_NOT_S64
,
383 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE
,
384 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE
,
385 [ FILTER_OP_UNARY_NOT_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE
,
388 [ FILTER_OP_AND
] = &&LABEL_FILTER_OP_AND
,
389 [ FILTER_OP_OR
] = &&LABEL_FILTER_OP_OR
,
390 [ FILTER_OP_AND_S64
] = &&LABEL_FILTER_OP_AND_S64
,
391 [ FILTER_OP_OR_S64
] = &&LABEL_FILTER_OP_OR_S64
,
392 [ FILTER_OP_AND_DOUBLE
] = &&LABEL_FILTER_OP_AND_DOUBLE
,
393 [ FILTER_OP_OR_DOUBLE
] = &&LABEL_FILTER_OP_OR_DOUBLE
,
396 [ FILTER_OP_LOAD_FIELD_REF
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF
,
397 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING
,
398 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE
,
399 [ FILTER_OP_LOAD_FIELD_REF_S64
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64
,
400 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE
,
402 [ FILTER_OP_LOAD_STRING
] = &&LABEL_FILTER_OP_LOAD_STRING
,
403 [ FILTER_OP_LOAD_S64
] = &&LABEL_FILTER_OP_LOAD_S64
,
404 [ FILTER_OP_LOAD_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_DOUBLE
,
406 #endif /* #ifndef INTERPRETER_USE_SWITCH */
410 OP(FILTER_OP_UNKNOWN
):
411 OP(FILTER_OP_LOAD_FIELD_REF
):
412 #ifdef INTERPRETER_USE_SWITCH
414 #endif /* INTERPRETER_USE_SWITCH */
415 ERR("unknown bytecode op %u\n",
416 (unsigned int) *(filter_opcode_t
*) pc
);
420 OP(FILTER_OP_RETURN
):
431 OP(FILTER_OP_RSHIFT
):
432 OP(FILTER_OP_LSHIFT
):
433 OP(FILTER_OP_BIN_AND
):
434 OP(FILTER_OP_BIN_OR
):
435 OP(FILTER_OP_BIN_XOR
):
436 ERR("unsupported bytecode op %u\n",
437 (unsigned int) *(filter_opcode_t
*) pc
);
447 ERR("unsupported non-specialized bytecode op %u\n",
448 (unsigned int) *(filter_opcode_t
*) pc
);
452 OP(FILTER_OP_EQ_STRING
):
454 reg
[REG_R0
].v
= (reg_strcmp(reg
, "==") == 0);
455 reg
[REG_R0
].type
= REG_S64
;
456 next_pc
+= sizeof(struct binary_op
);
459 OP(FILTER_OP_NE_STRING
):
461 reg
[REG_R0
].v
= (reg_strcmp(reg
, "!=") != 0);
462 reg
[REG_R0
].type
= REG_S64
;
463 next_pc
+= sizeof(struct binary_op
);
466 OP(FILTER_OP_GT_STRING
):
468 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">") > 0);
469 reg
[REG_R0
].type
= REG_S64
;
470 next_pc
+= sizeof(struct binary_op
);
473 OP(FILTER_OP_LT_STRING
):
475 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<") < 0);
476 reg
[REG_R0
].type
= REG_S64
;
477 next_pc
+= sizeof(struct binary_op
);
480 OP(FILTER_OP_GE_STRING
):
482 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">=") >= 0);
483 reg
[REG_R0
].type
= REG_S64
;
484 next_pc
+= sizeof(struct binary_op
);
487 OP(FILTER_OP_LE_STRING
):
489 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<=") <= 0);
490 reg
[REG_R0
].type
= REG_S64
;
491 next_pc
+= sizeof(struct binary_op
);
495 OP(FILTER_OP_EQ_S64
):
497 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].v
);
498 reg
[REG_R0
].type
= REG_S64
;
499 next_pc
+= sizeof(struct binary_op
);
502 OP(FILTER_OP_NE_S64
):
504 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].v
);
505 reg
[REG_R0
].type
= REG_S64
;
506 next_pc
+= sizeof(struct binary_op
);
509 OP(FILTER_OP_GT_S64
):
511 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].v
);
512 reg
[REG_R0
].type
= REG_S64
;
513 next_pc
+= sizeof(struct binary_op
);
516 OP(FILTER_OP_LT_S64
):
518 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].v
);
519 reg
[REG_R0
].type
= REG_S64
;
520 next_pc
+= sizeof(struct binary_op
);
523 OP(FILTER_OP_GE_S64
):
525 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].v
);
526 reg
[REG_R0
].type
= REG_S64
;
527 next_pc
+= sizeof(struct binary_op
);
530 OP(FILTER_OP_LE_S64
):
532 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].v
);
533 reg
[REG_R0
].type
= REG_S64
;
534 next_pc
+= sizeof(struct binary_op
);
538 OP(FILTER_OP_EQ_DOUBLE
):
540 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
541 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
542 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
543 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
544 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].d
);
545 reg
[REG_R0
].type
= REG_S64
;
546 next_pc
+= sizeof(struct binary_op
);
549 OP(FILTER_OP_NE_DOUBLE
):
551 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
552 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
553 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
554 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
555 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].d
);
556 reg
[REG_R0
].type
= REG_S64
;
557 next_pc
+= sizeof(struct binary_op
);
560 OP(FILTER_OP_GT_DOUBLE
):
562 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
563 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
564 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
565 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
566 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].d
);
567 reg
[REG_R0
].type
= REG_S64
;
568 next_pc
+= sizeof(struct binary_op
);
571 OP(FILTER_OP_LT_DOUBLE
):
573 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
574 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
575 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
576 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
577 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].d
);
578 reg
[REG_R0
].type
= REG_S64
;
579 next_pc
+= sizeof(struct binary_op
);
582 OP(FILTER_OP_GE_DOUBLE
):
584 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
585 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
586 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
587 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
588 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].d
);
589 reg
[REG_R0
].type
= REG_S64
;
590 next_pc
+= sizeof(struct binary_op
);
593 OP(FILTER_OP_LE_DOUBLE
):
595 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
596 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
597 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
598 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
599 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].d
);
600 reg
[REG_R0
].type
= REG_S64
;
601 next_pc
+= sizeof(struct binary_op
);
606 OP(FILTER_OP_UNARY_PLUS
):
607 OP(FILTER_OP_UNARY_MINUS
):
608 OP(FILTER_OP_UNARY_NOT
):
609 ERR("unsupported non-specialized bytecode op %u\n",
610 (unsigned int) *(filter_opcode_t
*) pc
);
615 OP(FILTER_OP_UNARY_PLUS_S64
):
616 OP(FILTER_OP_UNARY_PLUS_DOUBLE
):
618 next_pc
+= sizeof(struct unary_op
);
621 OP(FILTER_OP_UNARY_MINUS_S64
):
623 struct unary_op
*insn
= (struct unary_op
*) pc
;
625 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
626 next_pc
+= sizeof(struct unary_op
);
629 OP(FILTER_OP_UNARY_MINUS_DOUBLE
):
631 struct unary_op
*insn
= (struct unary_op
*) pc
;
633 reg
[insn
->reg
].d
= -reg
[insn
->reg
].d
;
634 next_pc
+= sizeof(struct unary_op
);
637 OP(FILTER_OP_UNARY_NOT_S64
):
639 struct unary_op
*insn
= (struct unary_op
*) pc
;
641 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
642 next_pc
+= sizeof(struct unary_op
);
645 OP(FILTER_OP_UNARY_NOT_DOUBLE
):
647 struct unary_op
*insn
= (struct unary_op
*) pc
;
649 reg
[insn
->reg
].d
= !reg
[insn
->reg
].d
;
650 next_pc
+= sizeof(struct unary_op
);
657 ERR("unsupported non-specialized bytecode op %u\n",
658 (unsigned int) *(filter_opcode_t
*) pc
);
662 OP(FILTER_OP_AND_S64
):
664 struct logical_op
*insn
= (struct logical_op
*) pc
;
666 /* If REG_R0 is 0, skip and evaluate to 0 */
667 if (unlikely(reg
[REG_R0
].v
== 0)) {
668 dbg_printf("Jumping to bytecode offset %u\n",
669 (unsigned int) insn
->skip_offset
);
670 next_pc
= start_pc
+ insn
->skip_offset
;
672 next_pc
+= sizeof(struct logical_op
);
676 OP(FILTER_OP_OR_S64
):
678 struct logical_op
*insn
= (struct logical_op
*) pc
;
680 /* If REG_R0 is nonzero, skip and evaluate to 1 */
682 if (unlikely(reg
[REG_R0
].v
!= 0)) {
684 dbg_printf("Jumping to bytecode offset %u\n",
685 (unsigned int) insn
->skip_offset
);
686 next_pc
= start_pc
+ insn
->skip_offset
;
688 next_pc
+= sizeof(struct logical_op
);
693 OP(FILTER_OP_AND_DOUBLE
):
695 struct logical_op
*insn
= (struct logical_op
*) pc
;
697 /* If REG_R0 is 0, skip and evaluate to 0 */
698 if ((reg
[REG_R0
].type
== REG_DOUBLE
&& unlikely(reg
[REG_R0
].d
== 0.0))
699 || (reg
[REG_R0
].type
== REG_S64
&& unlikely(reg
[REG_R0
].v
== 0))) {
700 dbg_printf("Jumping to bytecode offset %u\n",
701 (unsigned int) insn
->skip_offset
);
702 next_pc
= start_pc
+ insn
->skip_offset
;
704 next_pc
+= sizeof(struct logical_op
);
708 OP(FILTER_OP_OR_DOUBLE
):
710 struct logical_op
*insn
= (struct logical_op
*) pc
;
712 /* If REG_R0 is nonzero, skip and evaluate to 1 (in double) */
713 if ((reg
[REG_R0
].type
== REG_DOUBLE
&& unlikely(reg
[REG_R0
].d
!= 0.0))
714 || (reg
[REG_R0
].type
== REG_S64
&& unlikely(reg
[REG_R0
].v
!= 0))) {
716 dbg_printf("Jumping to bytecode offset %u\n",
717 (unsigned int) insn
->skip_offset
);
718 next_pc
= start_pc
+ insn
->skip_offset
;
720 next_pc
+= sizeof(struct logical_op
);
726 OP(FILTER_OP_LOAD_FIELD_REF_STRING
):
728 struct load_op
*insn
= (struct load_op
*) pc
;
729 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
731 dbg_printf("load field ref offset %u type string\n",
734 *(const char * const *) &filter_stack_data
[ref
->offset
];
735 reg
[insn
->reg
].type
= REG_STRING
;
736 reg
[insn
->reg
].seq_len
= UINT_MAX
;
737 reg
[insn
->reg
].literal
= 0;
738 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
739 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
743 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE
):
745 struct load_op
*insn
= (struct load_op
*) pc
;
746 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
748 dbg_printf("load field ref offset %u type sequence\n",
750 reg
[insn
->reg
].seq_len
=
751 *(unsigned long *) &filter_stack_data
[ref
->offset
];
753 *(const char **) (&filter_stack_data
[ref
->offset
754 + sizeof(unsigned long)]);
755 reg
[insn
->reg
].type
= REG_STRING
;
756 reg
[insn
->reg
].literal
= 0;
757 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
761 OP(FILTER_OP_LOAD_FIELD_REF_S64
):
763 struct load_op
*insn
= (struct load_op
*) pc
;
764 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
766 dbg_printf("load field ref offset %u type s64\n",
768 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
769 sizeof(struct literal_numeric
));
770 reg
[insn
->reg
].type
= REG_S64
;
771 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
772 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
776 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE
):
778 struct load_op
*insn
= (struct load_op
*) pc
;
779 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
781 dbg_printf("load field ref offset %u type double\n",
783 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
784 sizeof(struct literal_double
));
785 reg
[insn
->reg
].type
= REG_DOUBLE
;
786 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
787 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
791 OP(FILTER_OP_LOAD_STRING
):
793 struct load_op
*insn
= (struct load_op
*) pc
;
795 dbg_printf("load string %s\n", insn
->data
);
796 reg
[insn
->reg
].str
= insn
->data
;
797 reg
[insn
->reg
].type
= REG_STRING
;
798 reg
[insn
->reg
].seq_len
= UINT_MAX
;
799 reg
[insn
->reg
].literal
= 1;
800 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
804 OP(FILTER_OP_LOAD_S64
):
806 struct load_op
*insn
= (struct load_op
*) pc
;
808 memcpy(®
[insn
->reg
].v
, insn
->data
,
809 sizeof(struct literal_numeric
));
810 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
811 reg
[insn
->reg
].type
= REG_S64
;
812 next_pc
+= sizeof(struct load_op
)
813 + sizeof(struct literal_numeric
);
817 OP(FILTER_OP_LOAD_DOUBLE
):
819 struct load_op
*insn
= (struct load_op
*) pc
;
821 memcpy(®
[insn
->reg
].d
, insn
->data
,
822 sizeof(struct literal_double
));
823 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
824 reg
[insn
->reg
].type
= REG_DOUBLE
;
825 next_pc
+= sizeof(struct load_op
)
826 + sizeof(struct literal_double
);
832 /* return 0 (discard) on error */
844 int bin_op_compare_check(struct vreg reg
[NR_REG
], const char *str
)
846 switch (reg
[REG_R0
].type
) {
851 switch (reg
[REG_R1
].type
) {
864 switch (reg
[REG_R1
].type
) {
883 ERR("type mismatch for '%s' binary operator\n", str
);
888 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
890 void *pc
, *next_pc
, *start_pc
;
892 struct vreg reg
[NR_REG
];
895 for (i
= 0; i
< NR_REG
; i
++) {
896 reg
[i
].type
= REG_TYPE_UNKNOWN
;
900 start_pc
= &bytecode
->data
[0];
901 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
903 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
904 ERR("filter bytecode overflow\n");
908 dbg_printf("Validating op %s (%u)\n",
909 print_op((unsigned int) *(filter_opcode_t
*) pc
),
910 (unsigned int) *(filter_opcode_t
*) pc
);
911 switch (*(filter_opcode_t
*) pc
) {
912 case FILTER_OP_UNKNOWN
:
914 ERR("unknown bytecode op %u\n",
915 (unsigned int) *(filter_opcode_t
*) pc
);
919 case FILTER_OP_RETURN
:
928 case FILTER_OP_MINUS
:
929 case FILTER_OP_RSHIFT
:
930 case FILTER_OP_LSHIFT
:
931 case FILTER_OP_BIN_AND
:
932 case FILTER_OP_BIN_OR
:
933 case FILTER_OP_BIN_XOR
:
934 ERR("unsupported bytecode op %u\n",
935 (unsigned int) *(filter_opcode_t
*) pc
);
941 ret
= bin_op_compare_check(reg
, "==");
944 reg
[REG_R0
].type
= REG_S64
;
945 next_pc
+= sizeof(struct binary_op
);
950 ret
= bin_op_compare_check(reg
, "!=");
953 reg
[REG_R0
].type
= REG_S64
;
954 next_pc
+= sizeof(struct binary_op
);
959 ret
= bin_op_compare_check(reg
, ">");
962 reg
[REG_R0
].type
= REG_S64
;
963 next_pc
+= sizeof(struct binary_op
);
968 ret
= bin_op_compare_check(reg
, "<");
971 reg
[REG_R0
].type
= REG_S64
;
972 next_pc
+= sizeof(struct binary_op
);
977 ret
= bin_op_compare_check(reg
, ">=");
980 reg
[REG_R0
].type
= REG_S64
;
981 next_pc
+= sizeof(struct binary_op
);
986 ret
= bin_op_compare_check(reg
, "<=");
989 reg
[REG_R0
].type
= REG_S64
;
990 next_pc
+= sizeof(struct binary_op
);
994 case FILTER_OP_EQ_STRING
:
995 case FILTER_OP_NE_STRING
:
996 case FILTER_OP_GT_STRING
:
997 case FILTER_OP_LT_STRING
:
998 case FILTER_OP_GE_STRING
:
999 case FILTER_OP_LE_STRING
:
1001 if (reg
[REG_R0
].type
!= REG_STRING
1002 || reg
[REG_R1
].type
!= REG_STRING
) {
1003 ERR("Unexpected register type for string comparator\n");
1007 reg
[REG_R0
].type
= REG_S64
;
1008 next_pc
+= sizeof(struct binary_op
);
1012 case FILTER_OP_EQ_S64
:
1013 case FILTER_OP_NE_S64
:
1014 case FILTER_OP_GT_S64
:
1015 case FILTER_OP_LT_S64
:
1016 case FILTER_OP_GE_S64
:
1017 case FILTER_OP_LE_S64
:
1019 if (reg
[REG_R0
].type
!= REG_S64
1020 || reg
[REG_R1
].type
!= REG_S64
) {
1021 ERR("Unexpected register type for s64 comparator\n");
1025 reg
[REG_R0
].type
= REG_S64
;
1026 next_pc
+= sizeof(struct binary_op
);
1030 case FILTER_OP_EQ_DOUBLE
:
1031 case FILTER_OP_NE_DOUBLE
:
1032 case FILTER_OP_GT_DOUBLE
:
1033 case FILTER_OP_LT_DOUBLE
:
1034 case FILTER_OP_GE_DOUBLE
:
1035 case FILTER_OP_LE_DOUBLE
:
1037 if ((reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R0
].type
!= REG_S64
)
1038 || (reg
[REG_R1
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_S64
)) {
1039 ERR("Unexpected register type for double comparator\n");
1043 if (reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_DOUBLE
) {
1044 ERR("Double operator should have at least one double register\n");
1048 reg
[REG_R0
].type
= REG_DOUBLE
;
1049 next_pc
+= sizeof(struct binary_op
);
1054 case FILTER_OP_UNARY_PLUS
:
1055 case FILTER_OP_UNARY_MINUS
:
1056 case FILTER_OP_UNARY_NOT
:
1058 struct unary_op
*insn
= (struct unary_op
*) pc
;
1060 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1061 ERR("invalid register %u\n",
1062 (unsigned int) insn
->reg
);
1066 switch (reg
[insn
->reg
].type
) {
1068 ERR("unknown register type\n");
1073 ERR("Unary op can only be applied to numeric or floating point registers\n");
1081 next_pc
+= sizeof(struct unary_op
);
1085 case FILTER_OP_UNARY_PLUS_S64
:
1086 case FILTER_OP_UNARY_MINUS_S64
:
1087 case FILTER_OP_UNARY_NOT_S64
:
1089 struct unary_op
*insn
= (struct unary_op
*) pc
;
1091 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1092 ERR("invalid register %u\n",
1093 (unsigned int) insn
->reg
);
1097 if (reg
[insn
->reg
].type
!= REG_S64
) {
1098 ERR("Invalid register type\n");
1102 next_pc
+= sizeof(struct unary_op
);
1106 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1107 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1108 case FILTER_OP_UNARY_NOT_DOUBLE
:
1110 struct unary_op
*insn
= (struct unary_op
*) pc
;
1112 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1113 ERR("invalid register %u\n",
1114 (unsigned int) insn
->reg
);
1118 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
1119 ERR("Invalid register type\n");
1123 next_pc
+= sizeof(struct unary_op
);
1130 case FILTER_OP_AND_S64
:
1131 case FILTER_OP_OR_S64
:
1132 case FILTER_OP_AND_DOUBLE
:
1133 case FILTER_OP_OR_DOUBLE
:
1135 struct logical_op
*insn
= (struct logical_op
*) pc
;
1137 if (unlikely(reg
[REG_R0
].type
== REG_TYPE_UNKNOWN
1138 || reg
[REG_R1
].type
== REG_TYPE_UNKNOWN
1139 || reg
[REG_R0
].type
== REG_STRING
1140 || reg
[REG_R1
].type
== REG_STRING
)) {
1141 ERR("Logical comparator can only be applied to numeric and floating point registers\n");
1146 dbg_printf("Validate jumping to bytecode offset %u\n",
1147 (unsigned int) insn
->skip_offset
);
1148 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
1149 ERR("Loops are not allowed in bytecode\n");
1153 if (insn
->op
== FILTER_OP_AND_S64
1154 || insn
->op
== FILTER_OP_OR_S64
) {
1155 if (reg
[REG_R0
].type
!= REG_S64
1156 || reg
[REG_R1
].type
!= REG_S64
) {
1161 if (insn
->op
== FILTER_OP_AND_DOUBLE
1162 || insn
->op
== FILTER_OP_OR_DOUBLE
) {
1163 if (reg
[REG_R0
].type
!= REG_DOUBLE
1164 && reg
[REG_R1
].type
!= REG_DOUBLE
) {
1165 ERR("Double operator should have at least one double register\n");
1170 switch(reg
[REG_R0
].type
) {
1173 ERR("unknown register type\n");
1178 if (reg
[REG_R1
].type
== REG_S64
) {
1179 reg
[REG_R0
].type
= REG_S64
;
1181 reg
[REG_R0
].type
= REG_DOUBLE
;
1185 reg
[REG_R0
].type
= REG_DOUBLE
;
1188 next_pc
+= sizeof(struct logical_op
);
1193 case FILTER_OP_LOAD_FIELD_REF
:
1195 ERR("Unknown field ref type\n");
1199 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1200 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1202 struct load_op
*insn
= (struct load_op
*) pc
;
1203 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1205 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1206 ERR("invalid register %u\n",
1207 (unsigned int) insn
->reg
);
1211 dbg_printf("Validate load field ref offset %u type string\n",
1213 reg
[insn
->reg
].type
= REG_STRING
;
1214 reg
[insn
->reg
].literal
= 0;
1215 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1218 case FILTER_OP_LOAD_FIELD_REF_S64
:
1220 struct load_op
*insn
= (struct load_op
*) pc
;
1221 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1223 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1224 ERR("invalid register %u\n",
1225 (unsigned int) insn
->reg
);
1229 dbg_printf("Validate load field ref offset %u type s64\n",
1231 reg
[insn
->reg
].type
= REG_S64
;
1232 reg
[insn
->reg
].literal
= 0;
1233 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1236 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1238 struct load_op
*insn
= (struct load_op
*) pc
;
1239 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1241 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1242 ERR("invalid register %u\n",
1243 (unsigned int) insn
->reg
);
1247 dbg_printf("Validate load field ref offset %u type double\n",
1249 reg
[insn
->reg
].type
= REG_DOUBLE
;
1250 reg
[insn
->reg
].literal
= 0;
1251 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1255 case FILTER_OP_LOAD_STRING
:
1257 struct load_op
*insn
= (struct load_op
*) pc
;
1259 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1260 ERR("invalid register %u\n",
1261 (unsigned int) insn
->reg
);
1265 reg
[insn
->reg
].type
= REG_STRING
;
1266 reg
[insn
->reg
].literal
= 1;
1267 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1271 case FILTER_OP_LOAD_S64
:
1273 struct load_op
*insn
= (struct load_op
*) pc
;
1275 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1276 ERR("invalid register %u\n",
1277 (unsigned int) insn
->reg
);
1281 reg
[insn
->reg
].type
= REG_S64
;
1282 reg
[insn
->reg
].literal
= 1;
1283 next_pc
+= sizeof(struct load_op
)
1284 + sizeof(struct literal_numeric
);
1288 case FILTER_OP_LOAD_DOUBLE
:
1290 struct load_op
*insn
= (struct load_op
*) pc
;
1292 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1293 ERR("invalid register %u\n",
1294 (unsigned int) insn
->reg
);
1298 reg
[insn
->reg
].type
= REG_DOUBLE
;
1299 reg
[insn
->reg
].literal
= 1;
1300 next_pc
+= sizeof(struct load_op
)
1301 + sizeof(struct literal_double
);
1311 int lttng_filter_specialize_bytecode(struct bytecode_runtime
*bytecode
)
1313 void *pc
, *next_pc
, *start_pc
;
1315 struct vreg reg
[NR_REG
];
1318 for (i
= 0; i
< NR_REG
; i
++) {
1319 reg
[i
].type
= REG_TYPE_UNKNOWN
;
1323 start_pc
= &bytecode
->data
[0];
1324 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1326 switch (*(filter_opcode_t
*) pc
) {
1327 case FILTER_OP_UNKNOWN
:
1329 ERR("unknown bytecode op %u\n",
1330 (unsigned int) *(filter_opcode_t
*) pc
);
1334 case FILTER_OP_RETURN
:
1342 case FILTER_OP_PLUS
:
1343 case FILTER_OP_MINUS
:
1344 case FILTER_OP_RSHIFT
:
1345 case FILTER_OP_LSHIFT
:
1346 case FILTER_OP_BIN_AND
:
1347 case FILTER_OP_BIN_OR
:
1348 case FILTER_OP_BIN_XOR
:
1349 ERR("unsupported bytecode op %u\n",
1350 (unsigned int) *(filter_opcode_t
*) pc
);
1356 struct binary_op
*insn
= (struct binary_op
*) pc
;
1358 switch(reg
[REG_R0
].type
) {
1360 ERR("unknown register type\n");
1365 insn
->op
= FILTER_OP_EQ_STRING
;
1368 if (reg
[REG_R1
].type
== REG_S64
)
1369 insn
->op
= FILTER_OP_EQ_S64
;
1371 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1374 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1377 reg
[REG_R0
].type
= REG_S64
;
1378 next_pc
+= sizeof(struct binary_op
);
1384 struct binary_op
*insn
= (struct binary_op
*) pc
;
1386 switch(reg
[REG_R0
].type
) {
1388 ERR("unknown register type\n");
1393 insn
->op
= FILTER_OP_NE_STRING
;
1396 if (reg
[REG_R1
].type
== REG_S64
)
1397 insn
->op
= FILTER_OP_NE_S64
;
1399 insn
->op
= FILTER_OP_NE_DOUBLE
;
1402 insn
->op
= FILTER_OP_NE_DOUBLE
;
1405 reg
[REG_R0
].type
= REG_S64
;
1406 next_pc
+= sizeof(struct binary_op
);
1412 struct binary_op
*insn
= (struct binary_op
*) pc
;
1414 switch(reg
[REG_R0
].type
) {
1416 ERR("unknown register type\n");
1421 insn
->op
= FILTER_OP_GT_STRING
;
1424 if (reg
[REG_R1
].type
== REG_S64
)
1425 insn
->op
= FILTER_OP_GT_S64
;
1427 insn
->op
= FILTER_OP_GT_DOUBLE
;
1430 insn
->op
= FILTER_OP_GT_DOUBLE
;
1433 reg
[REG_R0
].type
= REG_S64
;
1434 next_pc
+= sizeof(struct binary_op
);
1440 struct binary_op
*insn
= (struct binary_op
*) pc
;
1442 switch(reg
[REG_R0
].type
) {
1444 ERR("unknown register type\n");
1449 insn
->op
= FILTER_OP_LT_STRING
;
1452 if (reg
[REG_R1
].type
== REG_S64
)
1453 insn
->op
= FILTER_OP_LT_S64
;
1455 insn
->op
= FILTER_OP_LT_DOUBLE
;
1458 insn
->op
= FILTER_OP_LT_DOUBLE
;
1461 reg
[REG_R0
].type
= REG_S64
;
1462 next_pc
+= sizeof(struct binary_op
);
1468 struct binary_op
*insn
= (struct binary_op
*) pc
;
1470 switch(reg
[REG_R0
].type
) {
1472 ERR("unknown register type\n");
1477 insn
->op
= FILTER_OP_GE_STRING
;
1480 if (reg
[REG_R1
].type
== REG_S64
)
1481 insn
->op
= FILTER_OP_GE_S64
;
1483 insn
->op
= FILTER_OP_GE_DOUBLE
;
1486 insn
->op
= FILTER_OP_GE_DOUBLE
;
1489 reg
[REG_R0
].type
= REG_S64
;
1490 next_pc
+= sizeof(struct binary_op
);
1495 struct binary_op
*insn
= (struct binary_op
*) pc
;
1497 switch(reg
[REG_R0
].type
) {
1499 ERR("unknown register type\n");
1504 insn
->op
= FILTER_OP_LE_STRING
;
1507 if (reg
[REG_R1
].type
== REG_S64
)
1508 insn
->op
= FILTER_OP_LE_S64
;
1510 insn
->op
= FILTER_OP_LE_DOUBLE
;
1513 insn
->op
= FILTER_OP_LE_DOUBLE
;
1516 reg
[REG_R0
].type
= REG_S64
;
1517 next_pc
+= sizeof(struct binary_op
);
1521 case FILTER_OP_EQ_STRING
:
1522 case FILTER_OP_NE_STRING
:
1523 case FILTER_OP_GT_STRING
:
1524 case FILTER_OP_LT_STRING
:
1525 case FILTER_OP_GE_STRING
:
1526 case FILTER_OP_LE_STRING
:
1527 case FILTER_OP_EQ_S64
:
1528 case FILTER_OP_NE_S64
:
1529 case FILTER_OP_GT_S64
:
1530 case FILTER_OP_LT_S64
:
1531 case FILTER_OP_GE_S64
:
1532 case FILTER_OP_LE_S64
:
1533 case FILTER_OP_EQ_DOUBLE
:
1534 case FILTER_OP_NE_DOUBLE
:
1535 case FILTER_OP_GT_DOUBLE
:
1536 case FILTER_OP_LT_DOUBLE
:
1537 case FILTER_OP_GE_DOUBLE
:
1538 case FILTER_OP_LE_DOUBLE
:
1540 reg
[REG_R0
].type
= REG_S64
;
1541 next_pc
+= sizeof(struct binary_op
);
1546 case FILTER_OP_UNARY_PLUS
:
1548 struct unary_op
*insn
= (struct unary_op
*) pc
;
1550 switch(reg
[insn
->reg
].type
) {
1552 ERR("unknown register type\n");
1557 insn
->op
= FILTER_OP_UNARY_PLUS_S64
;
1560 insn
->op
= FILTER_OP_UNARY_PLUS_DOUBLE
;
1563 next_pc
+= sizeof(struct unary_op
);
1567 case FILTER_OP_UNARY_MINUS
:
1569 struct unary_op
*insn
= (struct unary_op
*) pc
;
1571 switch(reg
[insn
->reg
].type
) {
1573 ERR("unknown register type\n");
1578 insn
->op
= FILTER_OP_UNARY_MINUS_S64
;
1581 insn
->op
= FILTER_OP_UNARY_MINUS_DOUBLE
;
1584 next_pc
+= sizeof(struct unary_op
);
1588 case FILTER_OP_UNARY_NOT
:
1590 struct unary_op
*insn
= (struct unary_op
*) pc
;
1592 switch(reg
[insn
->reg
].type
) {
1594 ERR("unknown register type\n");
1599 insn
->op
= FILTER_OP_UNARY_NOT_S64
;
1602 insn
->op
= FILTER_OP_UNARY_NOT_DOUBLE
;
1605 next_pc
+= sizeof(struct unary_op
);
1609 case FILTER_OP_UNARY_PLUS_S64
:
1610 case FILTER_OP_UNARY_MINUS_S64
:
1611 case FILTER_OP_UNARY_NOT_S64
:
1612 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1613 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1614 case FILTER_OP_UNARY_NOT_DOUBLE
:
1616 next_pc
+= sizeof(struct unary_op
);
1623 struct logical_op
*insn
= (struct logical_op
*) pc
;
1625 switch(reg
[REG_R0
].type
) {
1628 ERR("unknown register type\n");
1633 if (reg
[REG_R1
].type
== REG_S64
) {
1634 insn
->op
= FILTER_OP_AND_S64
;
1635 reg
[REG_R0
].type
= REG_S64
;
1637 insn
->op
= FILTER_OP_AND_DOUBLE
;
1638 reg
[REG_R0
].type
= REG_DOUBLE
;
1642 insn
->op
= FILTER_OP_AND_DOUBLE
;
1643 reg
[REG_R0
].type
= REG_DOUBLE
;
1646 next_pc
+= sizeof(struct logical_op
);
1651 struct logical_op
*insn
= (struct logical_op
*) pc
;
1653 switch(reg
[REG_R0
].type
) {
1656 ERR("unknown register type\n");
1661 if (reg
[REG_R1
].type
== REG_S64
) {
1662 insn
->op
= FILTER_OP_OR_S64
;
1663 reg
[REG_R0
].type
= REG_S64
;
1665 insn
->op
= FILTER_OP_OR_DOUBLE
;
1666 reg
[REG_R0
].type
= REG_DOUBLE
;
1670 insn
->op
= FILTER_OP_OR_DOUBLE
;
1671 reg
[REG_R0
].type
= REG_DOUBLE
;
1674 next_pc
+= sizeof(struct logical_op
);
1678 case FILTER_OP_AND_S64
:
1679 case FILTER_OP_OR_S64
:
1680 case FILTER_OP_AND_DOUBLE
:
1681 case FILTER_OP_OR_DOUBLE
:
1683 next_pc
+= sizeof(struct logical_op
);
1688 case FILTER_OP_LOAD_FIELD_REF
:
1690 ERR("Unknown field ref type\n");
1694 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1695 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1697 struct load_op
*insn
= (struct load_op
*) pc
;
1699 reg
[insn
->reg
].type
= REG_STRING
;
1700 reg
[insn
->reg
].literal
= 0;
1701 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1704 case FILTER_OP_LOAD_FIELD_REF_S64
:
1706 struct load_op
*insn
= (struct load_op
*) pc
;
1708 reg
[insn
->reg
].type
= REG_S64
;
1709 reg
[insn
->reg
].literal
= 0;
1710 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1713 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1715 struct load_op
*insn
= (struct load_op
*) pc
;
1717 reg
[insn
->reg
].type
= REG_DOUBLE
;
1718 reg
[insn
->reg
].literal
= 0;
1719 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1723 case FILTER_OP_LOAD_STRING
:
1725 struct load_op
*insn
= (struct load_op
*) pc
;
1727 reg
[insn
->reg
].type
= REG_STRING
;
1728 reg
[insn
->reg
].literal
= 1;
1729 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1733 case FILTER_OP_LOAD_S64
:
1735 struct load_op
*insn
= (struct load_op
*) pc
;
1737 reg
[insn
->reg
].type
= REG_S64
;
1738 reg
[insn
->reg
].literal
= 1;
1739 next_pc
+= sizeof(struct load_op
)
1740 + sizeof(struct literal_numeric
);
1744 case FILTER_OP_LOAD_DOUBLE
:
1746 struct load_op
*insn
= (struct load_op
*) pc
;
1748 reg
[insn
->reg
].type
= REG_DOUBLE
;
1749 reg
[insn
->reg
].literal
= 1;
1750 next_pc
+= sizeof(struct load_op
)
1751 + sizeof(struct literal_double
);
1763 int apply_field_reloc(struct ltt_event
*event
,
1764 struct bytecode_runtime
*runtime
,
1765 uint32_t runtime_len
,
1766 uint32_t reloc_offset
,
1767 const char *field_name
)
1769 const struct lttng_event_desc
*desc
;
1770 const struct lttng_event_field
*fields
, *field
= NULL
;
1771 unsigned int nr_fields
, i
;
1772 struct field_ref
*field_ref
;
1774 uint32_t field_offset
= 0;
1776 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1778 /* Ensure that the reloc is within the code */
1779 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1782 /* Lookup event by name */
1786 fields
= desc
->fields
;
1789 nr_fields
= desc
->nr_fields
;
1790 for (i
= 0; i
< nr_fields
; i
++) {
1791 if (!strcmp(fields
[i
].name
, field_name
)) {
1795 /* compute field offset */
1796 switch (fields
[i
].type
.atype
) {
1799 field_offset
+= sizeof(int64_t);
1802 case atype_sequence
:
1803 field_offset
+= sizeof(unsigned long);
1804 field_offset
+= sizeof(void *);
1807 field_offset
+= sizeof(void *);
1810 field_offset
+= sizeof(double);
1819 /* Check if field offset is too large for 16-bit offset */
1820 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1824 op
= (struct load_op
*) &runtime
->data
[reloc_offset
];
1825 field_ref
= (struct field_ref
*) op
->data
;
1826 switch (field
->type
.atype
) {
1829 op
->op
= FILTER_OP_LOAD_FIELD_REF_S64
;
1832 case atype_sequence
:
1833 op
->op
= FILTER_OP_LOAD_FIELD_REF_SEQUENCE
;
1836 op
->op
= FILTER_OP_LOAD_FIELD_REF_STRING
;
1839 op
->op
= FILTER_OP_LOAD_FIELD_REF_DOUBLE
;
1845 field_ref
->offset
= (uint16_t) field_offset
;
1850 * Take a bytecode with reloc table and link it to an event to create a
1854 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1855 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1857 int ret
, offset
, next_offset
;
1858 struct bytecode_runtime
*runtime
= NULL
;
1859 size_t runtime_alloc_len
;
1861 if (!filter_bytecode
)
1863 /* Even is not connected to any description */
1866 /* Bytecode already linked */
1867 if (event
->filter
|| event
->filter_data
)
1870 dbg_printf("Linking\n");
1872 /* We don't need the reloc table in the runtime */
1873 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
1874 runtime
= zmalloc(runtime_alloc_len
);
1879 runtime
->len
= filter_bytecode
->reloc_offset
;
1880 /* copy original bytecode */
1881 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
1883 * apply relocs. Those are a uint16_t (offset in bytecode)
1884 * followed by a string (field name).
1886 for (offset
= filter_bytecode
->reloc_offset
;
1887 offset
< filter_bytecode
->len
;
1888 offset
= next_offset
) {
1889 uint16_t reloc_offset
=
1890 *(uint16_t *) &filter_bytecode
->data
[offset
];
1891 const char *field_name
=
1892 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
1894 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1898 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1900 /* Validate bytecode */
1901 ret
= lttng_filter_validate_bytecode(runtime
);
1905 /* Specialize bytecode */
1906 ret
= lttng_filter_specialize_bytecode(runtime
);
1910 event
->filter_data
= runtime
;
1911 event
->filter
= lttng_filter_interpret_bytecode
;
1915 event
->filter
= lttng_filter_false
;
1920 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1921 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1925 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1927 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1932 * Link bytecode to all events for a wildcard. Skips events that already
1933 * have a bytecode linked.
1934 * We do not set each event's filter_bytecode field, because they do not
1935 * own the filter_bytecode: the wildcard owns it.
1937 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1939 struct ltt_event
*event
;
1942 if (!wildcard
->filter_bytecode
)
1945 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1948 ret
= _lttng_filter_event_link_bytecode(event
,
1949 wildcard
->filter_bytecode
);
1951 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1959 * Need to attach filter to an event before starting tracing for the
1960 * session. We own the filter_bytecode if we return success.
1962 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1963 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1965 if (event
->chan
->session
->been_active
)
1967 if (event
->filter_bytecode
)
1969 event
->filter_bytecode
= filter_bytecode
;
1974 * Need to attach filter to a wildcard before starting tracing for the
1975 * session. We own the filter_bytecode if we return success.
1977 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1978 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1980 if (wildcard
->chan
->session
->been_active
)
1982 if (wildcard
->filter_bytecode
)
1984 wildcard
->filter_bytecode
= filter_bytecode
;