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",
169 const char *print_op(enum filter_op op
)
171 if (op
>= NR_FILTER_OPS
)
178 * -1: wildcard found.
179 * -2: unknown escape char.
184 int parse_char(const char **p
)
204 int reg_strcmp(struct reg reg
[NR_REG
], const char *cmp_type
)
206 const char *p
= reg
[REG_R0
].str
, *q
= reg
[REG_R1
].str
;
213 if (unlikely(p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')) {
214 if (q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')
220 if (unlikely(q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')) {
221 if (p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')
227 if (reg
[REG_R0
].literal
) {
228 ret
= parse_char(&p
);
231 } else if (ret
== -2) {
234 /* else compare both char */
236 if (reg
[REG_R1
].literal
) {
237 ret
= parse_char(&q
);
240 } else if (ret
== -2) {
261 int lttng_filter_false(void *filter_data
,
262 const char *filter_stack_data
)
267 #ifdef INTERPRETER_USE_SWITCH
270 * Fallback for compilers that do not support taking address of labels.
274 start_pc = &bytecode->data[0]; \
275 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
277 dbg_printf("Executing op %s (%u)\n", \
278 print_op((unsigned int) *(filter_opcode_t *) pc), \
279 (unsigned int) *(filter_opcode_t *) pc); \
280 switch (*(filter_opcode_t *) pc) {
282 #define OP(name) case name
292 * Dispatch-table based interpreter.
296 start_pc = &bytecode->data[0]; \
297 pc = next_pc = start_pc; \
298 if (unlikely(pc - start_pc >= bytecode->len)) \
300 goto *dispatch[*(filter_opcode_t *) pc];
307 goto *dispatch[*(filter_opcode_t *) pc];
314 int lttng_filter_interpret_bytecode(void *filter_data
,
315 const char *filter_stack_data
)
317 struct bytecode_runtime
*bytecode
= filter_data
;
318 void *pc
, *next_pc
, *start_pc
;
321 struct reg reg
[NR_REG
];
322 #ifndef INTERPRETER_USE_SWITCH
323 static void *dispatch
[NR_FILTER_OPS
] = {
324 [ FILTER_OP_UNKNOWN
] = &&LABEL_FILTER_OP_UNKNOWN
,
326 [ FILTER_OP_RETURN
] = &&LABEL_FILTER_OP_RETURN
,
329 [ FILTER_OP_MUL
] = &&LABEL_FILTER_OP_MUL
,
330 [ FILTER_OP_DIV
] = &&LABEL_FILTER_OP_DIV
,
331 [ FILTER_OP_MOD
] = &&LABEL_FILTER_OP_MOD
,
332 [ FILTER_OP_PLUS
] = &&LABEL_FILTER_OP_PLUS
,
333 [ FILTER_OP_MINUS
] = &&LABEL_FILTER_OP_MINUS
,
334 [ FILTER_OP_RSHIFT
] = &&LABEL_FILTER_OP_RSHIFT
,
335 [ FILTER_OP_LSHIFT
] = &&LABEL_FILTER_OP_LSHIFT
,
336 [ FILTER_OP_BIN_AND
] = &&LABEL_FILTER_OP_BIN_AND
,
337 [ FILTER_OP_BIN_OR
] = &&LABEL_FILTER_OP_BIN_OR
,
338 [ FILTER_OP_BIN_XOR
] = &&LABEL_FILTER_OP_BIN_XOR
,
340 /* binary comparators */
341 [ FILTER_OP_EQ
] = &&LABEL_FILTER_OP_EQ
,
342 [ FILTER_OP_NE
] = &&LABEL_FILTER_OP_NE
,
343 [ FILTER_OP_GT
] = &&LABEL_FILTER_OP_GT
,
344 [ FILTER_OP_LT
] = &&LABEL_FILTER_OP_LT
,
345 [ FILTER_OP_GE
] = &&LABEL_FILTER_OP_GE
,
346 [ FILTER_OP_LE
] = &&LABEL_FILTER_OP_LE
,
348 /* string binary comparator */
349 [ FILTER_OP_EQ_STRING
] = &&LABEL_FILTER_OP_EQ_STRING
,
350 [ FILTER_OP_NE_STRING
] = &&LABEL_FILTER_OP_NE_STRING
,
351 [ FILTER_OP_GT_STRING
] = &&LABEL_FILTER_OP_GT_STRING
,
352 [ FILTER_OP_LT_STRING
] = &&LABEL_FILTER_OP_LT_STRING
,
353 [ FILTER_OP_GE_STRING
] = &&LABEL_FILTER_OP_GE_STRING
,
354 [ FILTER_OP_LE_STRING
] = &&LABEL_FILTER_OP_LE_STRING
,
356 /* s64 binary comparator */
357 [ FILTER_OP_EQ_S64
] = &&LABEL_FILTER_OP_EQ_S64
,
358 [ FILTER_OP_NE_S64
] = &&LABEL_FILTER_OP_NE_S64
,
359 [ FILTER_OP_GT_S64
] = &&LABEL_FILTER_OP_GT_S64
,
360 [ FILTER_OP_LT_S64
] = &&LABEL_FILTER_OP_LT_S64
,
361 [ FILTER_OP_GE_S64
] = &&LABEL_FILTER_OP_GE_S64
,
362 [ FILTER_OP_LE_S64
] = &&LABEL_FILTER_OP_LE_S64
,
364 /* double binary comparator */
365 [ FILTER_OP_EQ_DOUBLE
] = &&LABEL_FILTER_OP_EQ_DOUBLE
,
366 [ FILTER_OP_NE_DOUBLE
] = &&LABEL_FILTER_OP_NE_DOUBLE
,
367 [ FILTER_OP_GT_DOUBLE
] = &&LABEL_FILTER_OP_GT_DOUBLE
,
368 [ FILTER_OP_LT_DOUBLE
] = &&LABEL_FILTER_OP_LT_DOUBLE
,
369 [ FILTER_OP_GE_DOUBLE
] = &&LABEL_FILTER_OP_GE_DOUBLE
,
370 [ FILTER_OP_LE_DOUBLE
] = &&LABEL_FILTER_OP_LE_DOUBLE
,
373 [ FILTER_OP_UNARY_PLUS
] = &&LABEL_FILTER_OP_UNARY_PLUS
,
374 [ FILTER_OP_UNARY_MINUS
] = &&LABEL_FILTER_OP_UNARY_MINUS
,
375 [ FILTER_OP_UNARY_NOT
] = &&LABEL_FILTER_OP_UNARY_NOT
,
376 [ FILTER_OP_UNARY_PLUS_S64
] = &&LABEL_FILTER_OP_UNARY_PLUS_S64
,
377 [ FILTER_OP_UNARY_MINUS_S64
] = &&LABEL_FILTER_OP_UNARY_MINUS_S64
,
378 [ FILTER_OP_UNARY_NOT_S64
] = &&LABEL_FILTER_OP_UNARY_NOT_S64
,
379 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE
,
380 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE
,
381 [ FILTER_OP_UNARY_NOT_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE
,
384 [ FILTER_OP_AND
] = &&LABEL_FILTER_OP_AND
,
385 [ FILTER_OP_OR
] = &&LABEL_FILTER_OP_OR
,
388 [ FILTER_OP_LOAD_FIELD_REF
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF
,
389 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING
,
390 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE
,
391 [ FILTER_OP_LOAD_FIELD_REF_S64
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64
,
392 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE
,
394 [ FILTER_OP_LOAD_STRING
] = &&LABEL_FILTER_OP_LOAD_STRING
,
395 [ FILTER_OP_LOAD_S64
] = &&LABEL_FILTER_OP_LOAD_S64
,
396 [ FILTER_OP_LOAD_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_DOUBLE
,
398 #endif /* #ifndef INTERPRETER_USE_SWITCH */
402 OP(FILTER_OP_UNKNOWN
):
403 OP(FILTER_OP_LOAD_FIELD_REF
):
404 #ifdef INTERPRETER_USE_SWITCH
406 #endif /* INTERPRETER_USE_SWITCH */
407 ERR("unknown bytecode op %u\n",
408 (unsigned int) *(filter_opcode_t
*) pc
);
412 OP(FILTER_OP_RETURN
):
423 OP(FILTER_OP_RSHIFT
):
424 OP(FILTER_OP_LSHIFT
):
425 OP(FILTER_OP_BIN_AND
):
426 OP(FILTER_OP_BIN_OR
):
427 OP(FILTER_OP_BIN_XOR
):
428 ERR("unsupported bytecode op %u\n",
429 (unsigned int) *(filter_opcode_t
*) pc
);
439 ERR("unsupported non-specialized bytecode op %u\n",
440 (unsigned int) *(filter_opcode_t
*) pc
);
444 OP(FILTER_OP_EQ_STRING
):
446 reg
[REG_R0
].v
= (reg_strcmp(reg
, "==") == 0);
447 reg
[REG_R0
].type
= REG_S64
;
448 next_pc
+= sizeof(struct binary_op
);
451 OP(FILTER_OP_NE_STRING
):
453 reg
[REG_R0
].v
= (reg_strcmp(reg
, "!=") != 0);
454 reg
[REG_R0
].type
= REG_S64
;
455 next_pc
+= sizeof(struct binary_op
);
458 OP(FILTER_OP_GT_STRING
):
460 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">") > 0);
461 reg
[REG_R0
].type
= REG_S64
;
462 next_pc
+= sizeof(struct binary_op
);
465 OP(FILTER_OP_LT_STRING
):
467 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<") < 0);
468 reg
[REG_R0
].type
= REG_S64
;
469 next_pc
+= sizeof(struct binary_op
);
472 OP(FILTER_OP_GE_STRING
):
474 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">=") >= 0);
475 reg
[REG_R0
].type
= REG_S64
;
476 next_pc
+= sizeof(struct binary_op
);
479 OP(FILTER_OP_LE_STRING
):
481 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<=") <= 0);
482 reg
[REG_R0
].type
= REG_S64
;
483 next_pc
+= sizeof(struct binary_op
);
487 OP(FILTER_OP_EQ_S64
):
489 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].v
);
490 reg
[REG_R0
].type
= REG_S64
;
491 next_pc
+= sizeof(struct binary_op
);
494 OP(FILTER_OP_NE_S64
):
496 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].v
);
497 reg
[REG_R0
].type
= REG_S64
;
498 next_pc
+= sizeof(struct binary_op
);
501 OP(FILTER_OP_GT_S64
):
503 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].v
);
504 reg
[REG_R0
].type
= REG_S64
;
505 next_pc
+= sizeof(struct binary_op
);
508 OP(FILTER_OP_LT_S64
):
510 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].v
);
511 reg
[REG_R0
].type
= REG_S64
;
512 next_pc
+= sizeof(struct binary_op
);
515 OP(FILTER_OP_GE_S64
):
517 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].v
);
518 reg
[REG_R0
].type
= REG_S64
;
519 next_pc
+= sizeof(struct binary_op
);
522 OP(FILTER_OP_LE_S64
):
524 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].v
);
525 reg
[REG_R0
].type
= REG_S64
;
526 next_pc
+= sizeof(struct binary_op
);
530 OP(FILTER_OP_EQ_DOUBLE
):
532 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
533 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
534 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
535 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
536 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].d
);
537 reg
[REG_R0
].type
= REG_S64
;
538 next_pc
+= sizeof(struct binary_op
);
541 OP(FILTER_OP_NE_DOUBLE
):
543 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
544 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
545 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
546 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
547 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].d
);
548 reg
[REG_R0
].type
= REG_S64
;
549 next_pc
+= sizeof(struct binary_op
);
552 OP(FILTER_OP_GT_DOUBLE
):
554 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
555 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
556 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
557 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
558 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].d
);
559 reg
[REG_R0
].type
= REG_S64
;
560 next_pc
+= sizeof(struct binary_op
);
563 OP(FILTER_OP_LT_DOUBLE
):
565 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
566 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
567 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
568 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
569 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].d
);
570 reg
[REG_R0
].type
= REG_S64
;
571 next_pc
+= sizeof(struct binary_op
);
574 OP(FILTER_OP_GE_DOUBLE
):
576 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
577 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
578 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
579 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
580 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].d
);
581 reg
[REG_R0
].type
= REG_S64
;
582 next_pc
+= sizeof(struct binary_op
);
585 OP(FILTER_OP_LE_DOUBLE
):
587 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
588 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
589 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
590 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
591 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].d
);
592 reg
[REG_R0
].type
= REG_S64
;
593 next_pc
+= sizeof(struct binary_op
);
598 OP(FILTER_OP_UNARY_PLUS
):
599 OP(FILTER_OP_UNARY_MINUS
):
600 OP(FILTER_OP_UNARY_NOT
):
601 ERR("unsupported non-specialized bytecode op %u\n",
602 (unsigned int) *(filter_opcode_t
*) pc
);
607 OP(FILTER_OP_UNARY_PLUS_S64
):
608 OP(FILTER_OP_UNARY_PLUS_DOUBLE
):
610 next_pc
+= sizeof(struct unary_op
);
613 OP(FILTER_OP_UNARY_MINUS_S64
):
615 struct unary_op
*insn
= (struct unary_op
*) pc
;
617 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
618 next_pc
+= sizeof(struct unary_op
);
621 OP(FILTER_OP_UNARY_MINUS_DOUBLE
):
623 struct unary_op
*insn
= (struct unary_op
*) pc
;
625 reg
[insn
->reg
].d
= -reg
[insn
->reg
].d
;
626 next_pc
+= sizeof(struct unary_op
);
629 OP(FILTER_OP_UNARY_NOT_S64
):
631 struct unary_op
*insn
= (struct unary_op
*) pc
;
633 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
634 next_pc
+= sizeof(struct unary_op
);
637 OP(FILTER_OP_UNARY_NOT_DOUBLE
):
639 struct unary_op
*insn
= (struct unary_op
*) pc
;
641 reg
[insn
->reg
].d
= !reg
[insn
->reg
].d
;
642 next_pc
+= sizeof(struct unary_op
);
649 struct logical_op
*insn
= (struct logical_op
*) pc
;
651 /* If REG_R0 is 0, skip and evaluate to 0 */
652 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
== 0)
653 || unlikely(reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
== 0.0)) {
654 dbg_printf("Jumping to bytecode offset %u\n",
655 (unsigned int) insn
->skip_offset
);
656 next_pc
= start_pc
+ insn
->skip_offset
;
658 next_pc
+= sizeof(struct logical_op
);
664 struct logical_op
*insn
= (struct logical_op
*) pc
;
666 /* If REG_R0 is nonzero, skip and evaluate to 1 */
668 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
!= 0)
669 || unlikely(reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
!= 0.0)) {
671 dbg_printf("Jumping to bytecode offset %u\n",
672 (unsigned int) insn
->skip_offset
);
673 next_pc
= start_pc
+ insn
->skip_offset
;
675 next_pc
+= sizeof(struct logical_op
);
681 OP(FILTER_OP_LOAD_FIELD_REF_STRING
):
683 struct load_op
*insn
= (struct load_op
*) pc
;
684 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
686 dbg_printf("load field ref offset %u type string\n",
689 *(const char * const *) &filter_stack_data
[ref
->offset
];
690 reg
[insn
->reg
].type
= REG_STRING
;
691 reg
[insn
->reg
].seq_len
= UINT_MAX
;
692 reg
[insn
->reg
].literal
= 0;
693 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
694 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
698 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE
):
700 struct load_op
*insn
= (struct load_op
*) pc
;
701 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
703 dbg_printf("load field ref offset %u type sequence\n",
705 reg
[insn
->reg
].seq_len
=
706 *(unsigned long *) &filter_stack_data
[ref
->offset
];
708 *(const char **) (&filter_stack_data
[ref
->offset
709 + sizeof(unsigned long)]);
710 reg
[insn
->reg
].type
= REG_STRING
;
711 reg
[insn
->reg
].literal
= 0;
712 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
716 OP(FILTER_OP_LOAD_FIELD_REF_S64
):
718 struct load_op
*insn
= (struct load_op
*) pc
;
719 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
721 dbg_printf("load field ref offset %u type s64\n",
723 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
724 sizeof(struct literal_numeric
));
725 reg
[insn
->reg
].type
= REG_S64
;
726 reg
[insn
->reg
].literal
= 0;
727 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
728 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
732 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE
):
734 struct load_op
*insn
= (struct load_op
*) pc
;
735 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
737 dbg_printf("load field ref offset %u type double\n",
739 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
740 sizeof(struct literal_double
));
741 reg
[insn
->reg
].type
= REG_DOUBLE
;
742 reg
[insn
->reg
].literal
= 0;
743 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
744 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
748 OP(FILTER_OP_LOAD_STRING
):
750 struct load_op
*insn
= (struct load_op
*) pc
;
752 dbg_printf("load string %s\n", insn
->data
);
753 reg
[insn
->reg
].str
= insn
->data
;
754 reg
[insn
->reg
].type
= REG_STRING
;
755 reg
[insn
->reg
].seq_len
= UINT_MAX
;
756 reg
[insn
->reg
].literal
= 1;
757 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
761 OP(FILTER_OP_LOAD_S64
):
763 struct load_op
*insn
= (struct load_op
*) pc
;
765 memcpy(®
[insn
->reg
].v
, insn
->data
,
766 sizeof(struct literal_numeric
));
767 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
768 reg
[insn
->reg
].type
= REG_S64
;
769 reg
[insn
->reg
].literal
= 1;
770 next_pc
+= sizeof(struct load_op
)
771 + sizeof(struct literal_numeric
);
775 OP(FILTER_OP_LOAD_DOUBLE
):
777 struct load_op
*insn
= (struct load_op
*) pc
;
779 memcpy(®
[insn
->reg
].d
, insn
->data
,
780 sizeof(struct literal_double
));
781 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
782 reg
[insn
->reg
].type
= REG_DOUBLE
;
783 reg
[insn
->reg
].literal
= 1;
784 next_pc
+= sizeof(struct load_op
)
785 + sizeof(struct literal_double
);
791 /* return 0 (discard) on error */
803 int bin_op_compare_check(struct vreg reg
[NR_REG
], const char *str
)
805 switch (reg
[REG_R0
].type
) {
810 switch (reg
[REG_R1
].type
) {
823 switch (reg
[REG_R1
].type
) {
842 ERR("type mismatch for '%s' binary operator\n", str
);
847 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
849 void *pc
, *next_pc
, *start_pc
;
851 struct vreg reg
[NR_REG
];
854 for (i
= 0; i
< NR_REG
; i
++) {
855 reg
[i
].type
= REG_TYPE_UNKNOWN
;
859 start_pc
= &bytecode
->data
[0];
860 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
862 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
863 ERR("filter bytecode overflow\n");
867 dbg_printf("Validating op %s (%u)\n",
868 print_op((unsigned int) *(filter_opcode_t
*) pc
),
869 (unsigned int) *(filter_opcode_t
*) pc
);
870 switch (*(filter_opcode_t
*) pc
) {
871 case FILTER_OP_UNKNOWN
:
873 ERR("unknown bytecode op %u\n",
874 (unsigned int) *(filter_opcode_t
*) pc
);
878 case FILTER_OP_RETURN
:
887 case FILTER_OP_MINUS
:
888 case FILTER_OP_RSHIFT
:
889 case FILTER_OP_LSHIFT
:
890 case FILTER_OP_BIN_AND
:
891 case FILTER_OP_BIN_OR
:
892 case FILTER_OP_BIN_XOR
:
893 ERR("unsupported bytecode op %u\n",
894 (unsigned int) *(filter_opcode_t
*) pc
);
900 ret
= bin_op_compare_check(reg
, "==");
903 reg
[REG_R0
].type
= REG_S64
;
904 next_pc
+= sizeof(struct binary_op
);
909 ret
= bin_op_compare_check(reg
, "!=");
912 reg
[REG_R0
].type
= REG_S64
;
913 next_pc
+= sizeof(struct binary_op
);
918 ret
= bin_op_compare_check(reg
, ">");
921 reg
[REG_R0
].type
= REG_S64
;
922 next_pc
+= sizeof(struct binary_op
);
927 ret
= bin_op_compare_check(reg
, "<");
930 reg
[REG_R0
].type
= REG_S64
;
931 next_pc
+= sizeof(struct binary_op
);
936 ret
= bin_op_compare_check(reg
, ">=");
939 reg
[REG_R0
].type
= REG_S64
;
940 next_pc
+= sizeof(struct binary_op
);
945 ret
= bin_op_compare_check(reg
, "<=");
948 reg
[REG_R0
].type
= REG_S64
;
949 next_pc
+= sizeof(struct binary_op
);
953 case FILTER_OP_EQ_STRING
:
954 case FILTER_OP_NE_STRING
:
955 case FILTER_OP_GT_STRING
:
956 case FILTER_OP_LT_STRING
:
957 case FILTER_OP_GE_STRING
:
958 case FILTER_OP_LE_STRING
:
960 if (reg
[REG_R0
].type
!= REG_STRING
961 || reg
[REG_R1
].type
!= REG_STRING
) {
962 ERR("Unexpected register type for string comparator\n");
966 reg
[REG_R0
].type
= REG_S64
;
967 next_pc
+= sizeof(struct binary_op
);
971 case FILTER_OP_EQ_S64
:
972 case FILTER_OP_NE_S64
:
973 case FILTER_OP_GT_S64
:
974 case FILTER_OP_LT_S64
:
975 case FILTER_OP_GE_S64
:
976 case FILTER_OP_LE_S64
:
978 if (reg
[REG_R0
].type
!= REG_S64
979 || reg
[REG_R1
].type
!= REG_S64
) {
980 ERR("Unexpected register type for s64 comparator\n");
984 reg
[REG_R0
].type
= REG_S64
;
985 next_pc
+= sizeof(struct binary_op
);
989 case FILTER_OP_EQ_DOUBLE
:
990 case FILTER_OP_NE_DOUBLE
:
991 case FILTER_OP_GT_DOUBLE
:
992 case FILTER_OP_LT_DOUBLE
:
993 case FILTER_OP_GE_DOUBLE
:
994 case FILTER_OP_LE_DOUBLE
:
996 if ((reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R0
].type
!= REG_S64
)
997 || (reg
[REG_R1
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_S64
)) {
998 ERR("Unexpected register type for double comparator\n");
1002 reg
[REG_R0
].type
= REG_DOUBLE
;
1003 next_pc
+= sizeof(struct binary_op
);
1008 case FILTER_OP_UNARY_PLUS
:
1009 case FILTER_OP_UNARY_MINUS
:
1010 case FILTER_OP_UNARY_NOT
:
1012 struct unary_op
*insn
= (struct unary_op
*) pc
;
1014 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1015 ERR("invalid register %u\n",
1016 (unsigned int) insn
->reg
);
1020 switch (reg
[insn
->reg
].type
) {
1022 ERR("unknown register type\n");
1027 ERR("Unary op can only be applied to numeric or floating point registers\n");
1035 next_pc
+= sizeof(struct unary_op
);
1039 case FILTER_OP_UNARY_PLUS_S64
:
1040 case FILTER_OP_UNARY_MINUS_S64
:
1041 case FILTER_OP_UNARY_NOT_S64
:
1043 struct unary_op
*insn
= (struct unary_op
*) pc
;
1045 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1046 ERR("invalid register %u\n",
1047 (unsigned int) insn
->reg
);
1051 if (reg
[insn
->reg
].type
!= REG_S64
) {
1052 ERR("Invalid register type\n");
1056 next_pc
+= sizeof(struct unary_op
);
1060 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1061 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1062 case FILTER_OP_UNARY_NOT_DOUBLE
:
1064 struct unary_op
*insn
= (struct unary_op
*) pc
;
1066 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1067 ERR("invalid register %u\n",
1068 (unsigned int) insn
->reg
);
1072 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
1073 ERR("Invalid register type\n");
1077 next_pc
+= sizeof(struct unary_op
);
1085 struct logical_op
*insn
= (struct logical_op
*) pc
;
1087 if (unlikely(reg
[REG_R0
].type
== REG_TYPE_UNKNOWN
1088 || reg
[REG_R1
].type
== REG_TYPE_UNKNOWN
1089 || reg
[REG_R0
].type
== REG_STRING
1090 || reg
[REG_R1
].type
== REG_STRING
)) {
1091 ERR("Logical comparator can only be applied to numeric and floating point registers\n");
1096 dbg_printf("Validate jumping to bytecode offset %u\n",
1097 (unsigned int) insn
->skip_offset
);
1098 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
1099 ERR("Loops are not allowed in bytecode\n");
1103 next_pc
+= sizeof(struct logical_op
);
1108 case FILTER_OP_LOAD_FIELD_REF
:
1110 ERR("Unknown field ref type\n");
1114 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1115 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1117 struct load_op
*insn
= (struct load_op
*) pc
;
1118 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1120 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1121 ERR("invalid register %u\n",
1122 (unsigned int) insn
->reg
);
1126 dbg_printf("Validate load field ref offset %u type string\n",
1128 reg
[insn
->reg
].type
= REG_STRING
;
1129 reg
[insn
->reg
].literal
= 0;
1130 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1133 case FILTER_OP_LOAD_FIELD_REF_S64
:
1135 struct load_op
*insn
= (struct load_op
*) pc
;
1136 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1138 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1139 ERR("invalid register %u\n",
1140 (unsigned int) insn
->reg
);
1144 dbg_printf("Validate load field ref offset %u type s64\n",
1146 reg
[insn
->reg
].type
= REG_S64
;
1147 reg
[insn
->reg
].literal
= 0;
1148 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1151 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1153 struct load_op
*insn
= (struct load_op
*) pc
;
1154 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1156 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1157 ERR("invalid register %u\n",
1158 (unsigned int) insn
->reg
);
1162 dbg_printf("Validate load field ref offset %u type double\n",
1164 reg
[insn
->reg
].type
= REG_DOUBLE
;
1165 reg
[insn
->reg
].literal
= 0;
1166 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1170 case FILTER_OP_LOAD_STRING
:
1172 struct load_op
*insn
= (struct load_op
*) pc
;
1174 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1175 ERR("invalid register %u\n",
1176 (unsigned int) insn
->reg
);
1180 reg
[insn
->reg
].type
= REG_STRING
;
1181 reg
[insn
->reg
].literal
= 1;
1182 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1186 case FILTER_OP_LOAD_S64
:
1188 struct load_op
*insn
= (struct load_op
*) pc
;
1190 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1191 ERR("invalid register %u\n",
1192 (unsigned int) insn
->reg
);
1196 reg
[insn
->reg
].type
= REG_S64
;
1197 reg
[insn
->reg
].literal
= 1;
1198 next_pc
+= sizeof(struct load_op
)
1199 + sizeof(struct literal_numeric
);
1203 case FILTER_OP_LOAD_DOUBLE
:
1205 struct load_op
*insn
= (struct load_op
*) pc
;
1207 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1208 ERR("invalid register %u\n",
1209 (unsigned int) insn
->reg
);
1213 reg
[insn
->reg
].type
= REG_DOUBLE
;
1214 reg
[insn
->reg
].literal
= 1;
1215 next_pc
+= sizeof(struct load_op
)
1216 + sizeof(struct literal_double
);
1226 int lttng_filter_specialize_bytecode(struct bytecode_runtime
*bytecode
)
1228 void *pc
, *next_pc
, *start_pc
;
1230 struct vreg reg
[NR_REG
];
1233 for (i
= 0; i
< NR_REG
; i
++) {
1234 reg
[i
].type
= REG_TYPE_UNKNOWN
;
1238 start_pc
= &bytecode
->data
[0];
1239 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1241 switch (*(filter_opcode_t
*) pc
) {
1242 case FILTER_OP_UNKNOWN
:
1244 ERR("unknown bytecode op %u\n",
1245 (unsigned int) *(filter_opcode_t
*) pc
);
1249 case FILTER_OP_RETURN
:
1257 case FILTER_OP_PLUS
:
1258 case FILTER_OP_MINUS
:
1259 case FILTER_OP_RSHIFT
:
1260 case FILTER_OP_LSHIFT
:
1261 case FILTER_OP_BIN_AND
:
1262 case FILTER_OP_BIN_OR
:
1263 case FILTER_OP_BIN_XOR
:
1264 ERR("unsupported bytecode op %u\n",
1265 (unsigned int) *(filter_opcode_t
*) pc
);
1271 struct binary_op
*insn
= (struct binary_op
*) pc
;
1273 switch(reg
[REG_R0
].type
) {
1275 ERR("unknown register type\n");
1280 insn
->op
= FILTER_OP_EQ_STRING
;
1283 if (reg
[REG_R1
].type
== REG_S64
)
1284 insn
->op
= FILTER_OP_EQ_S64
;
1286 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1289 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1292 reg
[REG_R0
].type
= REG_S64
;
1293 next_pc
+= sizeof(struct binary_op
);
1299 struct binary_op
*insn
= (struct binary_op
*) pc
;
1301 switch(reg
[REG_R0
].type
) {
1303 ERR("unknown register type\n");
1308 insn
->op
= FILTER_OP_NE_STRING
;
1311 if (reg
[REG_R1
].type
== REG_S64
)
1312 insn
->op
= FILTER_OP_NE_S64
;
1314 insn
->op
= FILTER_OP_NE_DOUBLE
;
1317 insn
->op
= FILTER_OP_NE_DOUBLE
;
1320 reg
[REG_R0
].type
= REG_S64
;
1321 next_pc
+= sizeof(struct binary_op
);
1327 struct binary_op
*insn
= (struct binary_op
*) pc
;
1329 switch(reg
[REG_R0
].type
) {
1331 ERR("unknown register type\n");
1336 insn
->op
= FILTER_OP_GT_STRING
;
1339 if (reg
[REG_R1
].type
== REG_S64
)
1340 insn
->op
= FILTER_OP_GT_S64
;
1342 insn
->op
= FILTER_OP_GT_DOUBLE
;
1345 insn
->op
= FILTER_OP_GT_DOUBLE
;
1348 reg
[REG_R0
].type
= REG_S64
;
1349 next_pc
+= sizeof(struct binary_op
);
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_LT_STRING
;
1367 if (reg
[REG_R1
].type
== REG_S64
)
1368 insn
->op
= FILTER_OP_LT_S64
;
1370 insn
->op
= FILTER_OP_LT_DOUBLE
;
1373 insn
->op
= FILTER_OP_LT_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_GE_STRING
;
1395 if (reg
[REG_R1
].type
== REG_S64
)
1396 insn
->op
= FILTER_OP_GE_S64
;
1398 insn
->op
= FILTER_OP_GE_DOUBLE
;
1401 insn
->op
= FILTER_OP_GE_DOUBLE
;
1404 reg
[REG_R0
].type
= REG_S64
;
1405 next_pc
+= sizeof(struct binary_op
);
1410 struct binary_op
*insn
= (struct binary_op
*) pc
;
1412 switch(reg
[REG_R0
].type
) {
1414 ERR("unknown register type\n");
1419 insn
->op
= FILTER_OP_LE_STRING
;
1422 if (reg
[REG_R1
].type
== REG_S64
)
1423 insn
->op
= FILTER_OP_LE_S64
;
1425 insn
->op
= FILTER_OP_LE_DOUBLE
;
1428 insn
->op
= FILTER_OP_LE_DOUBLE
;
1431 reg
[REG_R0
].type
= REG_S64
;
1432 next_pc
+= sizeof(struct binary_op
);
1436 case FILTER_OP_EQ_STRING
:
1437 case FILTER_OP_NE_STRING
:
1438 case FILTER_OP_GT_STRING
:
1439 case FILTER_OP_LT_STRING
:
1440 case FILTER_OP_GE_STRING
:
1441 case FILTER_OP_LE_STRING
:
1442 case FILTER_OP_EQ_S64
:
1443 case FILTER_OP_NE_S64
:
1444 case FILTER_OP_GT_S64
:
1445 case FILTER_OP_LT_S64
:
1446 case FILTER_OP_GE_S64
:
1447 case FILTER_OP_LE_S64
:
1448 case FILTER_OP_EQ_DOUBLE
:
1449 case FILTER_OP_NE_DOUBLE
:
1450 case FILTER_OP_GT_DOUBLE
:
1451 case FILTER_OP_LT_DOUBLE
:
1452 case FILTER_OP_GE_DOUBLE
:
1453 case FILTER_OP_LE_DOUBLE
:
1455 reg
[REG_R0
].type
= REG_S64
;
1456 next_pc
+= sizeof(struct binary_op
);
1461 case FILTER_OP_UNARY_PLUS
:
1463 struct unary_op
*insn
= (struct unary_op
*) pc
;
1465 switch(reg
[insn
->reg
].type
) {
1467 ERR("unknown register type\n");
1472 insn
->op
= FILTER_OP_UNARY_PLUS_S64
;
1475 insn
->op
= FILTER_OP_UNARY_PLUS_DOUBLE
;
1481 case FILTER_OP_UNARY_MINUS
:
1483 struct unary_op
*insn
= (struct unary_op
*) pc
;
1485 switch(reg
[insn
->reg
].type
) {
1487 ERR("unknown register type\n");
1492 insn
->op
= FILTER_OP_UNARY_MINUS_S64
;
1495 insn
->op
= FILTER_OP_UNARY_MINUS_DOUBLE
;
1501 case FILTER_OP_UNARY_NOT
:
1503 struct unary_op
*insn
= (struct unary_op
*) pc
;
1505 switch(reg
[insn
->reg
].type
) {
1507 ERR("unknown register type\n");
1512 insn
->op
= FILTER_OP_UNARY_NOT_S64
;
1515 insn
->op
= FILTER_OP_UNARY_NOT_DOUBLE
;
1521 case FILTER_OP_UNARY_PLUS_S64
:
1522 case FILTER_OP_UNARY_MINUS_S64
:
1523 case FILTER_OP_UNARY_NOT_S64
:
1524 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1525 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1526 case FILTER_OP_UNARY_NOT_DOUBLE
:
1528 next_pc
+= sizeof(struct unary_op
);
1536 next_pc
+= sizeof(struct logical_op
);
1541 case FILTER_OP_LOAD_FIELD_REF
:
1543 ERR("Unknown field ref type\n");
1547 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1548 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1550 struct load_op
*insn
= (struct load_op
*) pc
;
1552 reg
[insn
->reg
].type
= REG_STRING
;
1553 reg
[insn
->reg
].literal
= 0;
1554 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1557 case FILTER_OP_LOAD_FIELD_REF_S64
:
1559 struct load_op
*insn
= (struct load_op
*) pc
;
1561 reg
[insn
->reg
].type
= REG_S64
;
1562 reg
[insn
->reg
].literal
= 0;
1563 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1566 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1568 struct load_op
*insn
= (struct load_op
*) pc
;
1570 reg
[insn
->reg
].type
= REG_DOUBLE
;
1571 reg
[insn
->reg
].literal
= 0;
1572 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1576 case FILTER_OP_LOAD_STRING
:
1578 struct load_op
*insn
= (struct load_op
*) pc
;
1580 reg
[insn
->reg
].type
= REG_STRING
;
1581 reg
[insn
->reg
].literal
= 1;
1582 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1586 case FILTER_OP_LOAD_S64
:
1588 struct load_op
*insn
= (struct load_op
*) pc
;
1590 reg
[insn
->reg
].type
= REG_S64
;
1591 reg
[insn
->reg
].literal
= 1;
1592 next_pc
+= sizeof(struct load_op
)
1593 + sizeof(struct literal_numeric
);
1597 case FILTER_OP_LOAD_DOUBLE
:
1599 struct load_op
*insn
= (struct load_op
*) pc
;
1601 reg
[insn
->reg
].type
= REG_DOUBLE
;
1602 reg
[insn
->reg
].literal
= 1;
1603 next_pc
+= sizeof(struct load_op
)
1604 + sizeof(struct literal_double
);
1616 int apply_field_reloc(struct ltt_event
*event
,
1617 struct bytecode_runtime
*runtime
,
1618 uint32_t runtime_len
,
1619 uint32_t reloc_offset
,
1620 const char *field_name
)
1622 const struct lttng_event_desc
*desc
;
1623 const struct lttng_event_field
*fields
, *field
= NULL
;
1624 unsigned int nr_fields
, i
;
1625 struct field_ref
*field_ref
;
1627 uint32_t field_offset
= 0;
1629 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1631 /* Ensure that the reloc is within the code */
1632 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1635 /* Lookup event by name */
1639 fields
= desc
->fields
;
1642 nr_fields
= desc
->nr_fields
;
1643 for (i
= 0; i
< nr_fields
; i
++) {
1644 if (!strcmp(fields
[i
].name
, field_name
)) {
1648 /* compute field offset */
1649 switch (fields
[i
].type
.atype
) {
1652 field_offset
+= sizeof(int64_t);
1655 case atype_sequence
:
1656 field_offset
+= sizeof(unsigned long);
1657 field_offset
+= sizeof(void *);
1660 field_offset
+= sizeof(void *);
1663 field_offset
+= sizeof(double);
1672 /* Check if field offset is too large for 16-bit offset */
1673 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1677 op
= (struct load_op
*) &runtime
->data
[reloc_offset
];
1678 field_ref
= (struct field_ref
*) op
->data
;
1679 switch (field
->type
.atype
) {
1682 op
->op
= FILTER_OP_LOAD_FIELD_REF_S64
;
1685 case atype_sequence
:
1686 op
->op
= FILTER_OP_LOAD_FIELD_REF_SEQUENCE
;
1689 op
->op
= FILTER_OP_LOAD_FIELD_REF_STRING
;
1692 op
->op
= FILTER_OP_LOAD_FIELD_REF_DOUBLE
;
1698 field_ref
->offset
= (uint16_t) field_offset
;
1703 * Take a bytecode with reloc table and link it to an event to create a
1707 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1708 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1710 int ret
, offset
, next_offset
;
1711 struct bytecode_runtime
*runtime
= NULL
;
1712 size_t runtime_alloc_len
;
1714 if (!filter_bytecode
)
1716 /* Even is not connected to any description */
1719 /* Bytecode already linked */
1720 if (event
->filter
|| event
->filter_data
)
1723 dbg_printf("Linking\n");
1725 /* We don't need the reloc table in the runtime */
1726 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
1727 runtime
= zmalloc(runtime_alloc_len
);
1732 runtime
->len
= filter_bytecode
->reloc_offset
;
1733 /* copy original bytecode */
1734 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
1736 * apply relocs. Those are a uint16_t (offset in bytecode)
1737 * followed by a string (field name).
1739 for (offset
= filter_bytecode
->reloc_offset
;
1740 offset
< filter_bytecode
->len
;
1741 offset
= next_offset
) {
1742 uint16_t reloc_offset
=
1743 *(uint16_t *) &filter_bytecode
->data
[offset
];
1744 const char *field_name
=
1745 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
1747 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1751 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1753 /* Validate bytecode */
1754 ret
= lttng_filter_validate_bytecode(runtime
);
1758 /* Specialize bytecode */
1759 ret
= lttng_filter_specialize_bytecode(runtime
);
1763 event
->filter_data
= runtime
;
1764 event
->filter
= lttng_filter_interpret_bytecode
;
1768 event
->filter
= lttng_filter_false
;
1773 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1774 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1778 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1780 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1785 * Link bytecode to all events for a wildcard. Skips events that already
1786 * have a bytecode linked.
1787 * We do not set each event's filter_bytecode field, because they do not
1788 * own the filter_bytecode: the wildcard owns it.
1790 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1792 struct ltt_event
*event
;
1795 if (!wildcard
->filter_bytecode
)
1798 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1801 ret
= _lttng_filter_event_link_bytecode(event
,
1802 wildcard
->filter_bytecode
);
1804 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1812 * Need to attach filter to an event before starting tracing for the
1813 * session. We own the filter_bytecode if we return success.
1815 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1816 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1818 if (event
->chan
->session
->been_active
)
1820 if (event
->filter_bytecode
)
1822 event
->filter_bytecode
= filter_bytecode
;
1827 * Need to attach filter to a wildcard before starting tracing for the
1828 * session. We own the filter_bytecode if we return success.
1830 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1831 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1833 if (wildcard
->chan
->session
->been_active
)
1835 if (wildcard
->filter_bytecode
)
1837 wildcard
->filter_bytecode
= filter_bytecode
;