2 * lttng-filter-interpreter.c
4 * LTTng UST filter interpreter.
6 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 #include <urcu-pointer.h>
29 #include "lttng-filter.h"
30 #include "string-utils.h"
34 * -2: unknown escape char.
39 int parse_char(const char **p
)
59 * Returns -1ULL if the string is null-terminated, or the number of
63 size_t get_str_or_seq_len(const struct estack_entry
*entry
)
65 if (entry
->u
.s
.seq_len
== UINT_MAX
) {
68 return entry
->u
.s
.seq_len
;
73 int stack_star_glob_match(struct estack
*stack
, int top
, const char *cmp_type
)
76 const char *candidate
;
80 /* Find out which side is the pattern vs. the candidate. */
81 if (estack_ax(stack
, top
)->u
.s
.literal_type
== ESTACK_STRING_LITERAL_TYPE_STAR_GLOB
) {
82 pattern
= estack_ax(stack
, top
)->u
.s
.str
;
83 pattern_len
= get_str_or_seq_len(estack_ax(stack
, top
));
84 candidate
= estack_bx(stack
, top
)->u
.s
.str
;
85 candidate_len
= get_str_or_seq_len(estack_bx(stack
, top
));
87 pattern
= estack_bx(stack
, top
)->u
.s
.str
;
88 pattern_len
= get_str_or_seq_len(estack_bx(stack
, top
));
89 candidate
= estack_ax(stack
, top
)->u
.s
.str
;
90 candidate_len
= get_str_or_seq_len(estack_ax(stack
, top
));
93 /* Perform the match. Returns 0 when the result is true. */
94 return !strutils_star_glob_match(pattern
, pattern_len
, candidate
,
99 int stack_strcmp(struct estack
*stack
, int top
, const char *cmp_type
)
101 const char *p
= estack_bx(stack
, top
)->u
.s
.str
, *q
= estack_ax(stack
, top
)->u
.s
.str
;
108 if (unlikely(p
- estack_bx(stack
, top
)->u
.s
.str
>= estack_bx(stack
, top
)->u
.s
.seq_len
|| *p
== '\0')) {
109 if (q
- estack_ax(stack
, top
)->u
.s
.str
>= estack_ax(stack
, top
)->u
.s
.seq_len
|| *q
== '\0') {
112 if (estack_ax(stack
, top
)->u
.s
.literal_type
==
113 ESTACK_STRING_LITERAL_TYPE_PLAIN
) {
114 ret
= parse_char(&q
);
121 if (unlikely(q
- estack_ax(stack
, top
)->u
.s
.str
>= estack_ax(stack
, top
)->u
.s
.seq_len
|| *q
== '\0')) {
122 if (estack_bx(stack
, top
)->u
.s
.literal_type
==
123 ESTACK_STRING_LITERAL_TYPE_PLAIN
) {
124 ret
= parse_char(&p
);
130 if (estack_bx(stack
, top
)->u
.s
.literal_type
==
131 ESTACK_STRING_LITERAL_TYPE_PLAIN
) {
132 ret
= parse_char(&p
);
135 } else if (ret
== -2) {
138 /* else compare both char */
140 if (estack_ax(stack
, top
)->u
.s
.literal_type
==
141 ESTACK_STRING_LITERAL_TYPE_PLAIN
) {
142 ret
= parse_char(&q
);
145 } else if (ret
== -2) {
165 uint64_t lttng_filter_false(void *filter_data
,
166 const char *filter_stack_data
)
171 #ifdef INTERPRETER_USE_SWITCH
174 * Fallback for compilers that do not support taking address of labels.
178 start_pc = &bytecode->data[0]; \
179 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
181 dbg_printf("Executing op %s (%u)\n", \
182 print_op((unsigned int) *(filter_opcode_t *) pc), \
183 (unsigned int) *(filter_opcode_t *) pc); \
184 switch (*(filter_opcode_t *) pc) {
186 #define OP(name) jump_target_##name: __attribute__((unused)); \
194 #define JUMP_TO(name) \
195 goto jump_target_##name
200 * Dispatch-table based interpreter.
204 start_pc = &bytecode->data[0]; \
205 pc = next_pc = start_pc; \
206 if (unlikely(pc - start_pc >= bytecode->len)) \
208 goto *dispatch[*(filter_opcode_t *) pc];
215 goto *dispatch[*(filter_opcode_t *) pc];
219 #define JUMP_TO(name) \
225 * Return 0 (discard), or raise the 0x1 flag (log event).
226 * Currently, other flags are kept for future extensions and have no
229 uint64_t lttng_filter_interpret_bytecode(void *filter_data
,
230 const char *filter_stack_data
)
232 struct bytecode_runtime
*bytecode
= filter_data
;
233 struct lttng_session
*session
= bytecode
->p
.session
;
234 void *pc
, *next_pc
, *start_pc
;
237 struct estack _stack
;
238 struct estack
*stack
= &_stack
;
239 register int64_t ax
= 0, bx
= 0;
240 register enum entry_type ax_t
= REG_UNKNOWN
, bx_t
= REG_UNKNOWN
;
241 register int top
= FILTER_STACK_EMPTY
;
242 #ifndef INTERPRETER_USE_SWITCH
243 static void *dispatch
[NR_FILTER_OPS
] = {
244 [ FILTER_OP_UNKNOWN
] = &&LABEL_FILTER_OP_UNKNOWN
,
246 [ FILTER_OP_RETURN
] = &&LABEL_FILTER_OP_RETURN
,
249 [ FILTER_OP_MUL
] = &&LABEL_FILTER_OP_MUL
,
250 [ FILTER_OP_DIV
] = &&LABEL_FILTER_OP_DIV
,
251 [ FILTER_OP_MOD
] = &&LABEL_FILTER_OP_MOD
,
252 [ FILTER_OP_PLUS
] = &&LABEL_FILTER_OP_PLUS
,
253 [ FILTER_OP_MINUS
] = &&LABEL_FILTER_OP_MINUS
,
254 [ FILTER_OP_RSHIFT
] = &&LABEL_FILTER_OP_RSHIFT
,
255 [ FILTER_OP_LSHIFT
] = &&LABEL_FILTER_OP_LSHIFT
,
256 [ FILTER_OP_BIN_AND
] = &&LABEL_FILTER_OP_BIN_AND
,
257 [ FILTER_OP_BIN_OR
] = &&LABEL_FILTER_OP_BIN_OR
,
258 [ FILTER_OP_BIN_XOR
] = &&LABEL_FILTER_OP_BIN_XOR
,
260 /* binary comparators */
261 [ FILTER_OP_EQ
] = &&LABEL_FILTER_OP_EQ
,
262 [ FILTER_OP_NE
] = &&LABEL_FILTER_OP_NE
,
263 [ FILTER_OP_GT
] = &&LABEL_FILTER_OP_GT
,
264 [ FILTER_OP_LT
] = &&LABEL_FILTER_OP_LT
,
265 [ FILTER_OP_GE
] = &&LABEL_FILTER_OP_GE
,
266 [ FILTER_OP_LE
] = &&LABEL_FILTER_OP_LE
,
268 /* string binary comparator */
269 [ FILTER_OP_EQ_STRING
] = &&LABEL_FILTER_OP_EQ_STRING
,
270 [ FILTER_OP_NE_STRING
] = &&LABEL_FILTER_OP_NE_STRING
,
271 [ FILTER_OP_GT_STRING
] = &&LABEL_FILTER_OP_GT_STRING
,
272 [ FILTER_OP_LT_STRING
] = &&LABEL_FILTER_OP_LT_STRING
,
273 [ FILTER_OP_GE_STRING
] = &&LABEL_FILTER_OP_GE_STRING
,
274 [ FILTER_OP_LE_STRING
] = &&LABEL_FILTER_OP_LE_STRING
,
276 /* globbing pattern binary comparator */
277 [ FILTER_OP_EQ_STAR_GLOB_STRING
] = &&LABEL_FILTER_OP_EQ_STAR_GLOB_STRING
,
278 [ FILTER_OP_NE_STAR_GLOB_STRING
] = &&LABEL_FILTER_OP_NE_STAR_GLOB_STRING
,
280 /* s64 binary comparator */
281 [ FILTER_OP_EQ_S64
] = &&LABEL_FILTER_OP_EQ_S64
,
282 [ FILTER_OP_NE_S64
] = &&LABEL_FILTER_OP_NE_S64
,
283 [ FILTER_OP_GT_S64
] = &&LABEL_FILTER_OP_GT_S64
,
284 [ FILTER_OP_LT_S64
] = &&LABEL_FILTER_OP_LT_S64
,
285 [ FILTER_OP_GE_S64
] = &&LABEL_FILTER_OP_GE_S64
,
286 [ FILTER_OP_LE_S64
] = &&LABEL_FILTER_OP_LE_S64
,
288 /* double binary comparator */
289 [ FILTER_OP_EQ_DOUBLE
] = &&LABEL_FILTER_OP_EQ_DOUBLE
,
290 [ FILTER_OP_NE_DOUBLE
] = &&LABEL_FILTER_OP_NE_DOUBLE
,
291 [ FILTER_OP_GT_DOUBLE
] = &&LABEL_FILTER_OP_GT_DOUBLE
,
292 [ FILTER_OP_LT_DOUBLE
] = &&LABEL_FILTER_OP_LT_DOUBLE
,
293 [ FILTER_OP_GE_DOUBLE
] = &&LABEL_FILTER_OP_GE_DOUBLE
,
294 [ FILTER_OP_LE_DOUBLE
] = &&LABEL_FILTER_OP_LE_DOUBLE
,
296 /* Mixed S64-double binary comparators */
297 [ FILTER_OP_EQ_DOUBLE_S64
] = &&LABEL_FILTER_OP_EQ_DOUBLE_S64
,
298 [ FILTER_OP_NE_DOUBLE_S64
] = &&LABEL_FILTER_OP_NE_DOUBLE_S64
,
299 [ FILTER_OP_GT_DOUBLE_S64
] = &&LABEL_FILTER_OP_GT_DOUBLE_S64
,
300 [ FILTER_OP_LT_DOUBLE_S64
] = &&LABEL_FILTER_OP_LT_DOUBLE_S64
,
301 [ FILTER_OP_GE_DOUBLE_S64
] = &&LABEL_FILTER_OP_GE_DOUBLE_S64
,
302 [ FILTER_OP_LE_DOUBLE_S64
] = &&LABEL_FILTER_OP_LE_DOUBLE_S64
,
304 [ FILTER_OP_EQ_S64_DOUBLE
] = &&LABEL_FILTER_OP_EQ_S64_DOUBLE
,
305 [ FILTER_OP_NE_S64_DOUBLE
] = &&LABEL_FILTER_OP_NE_S64_DOUBLE
,
306 [ FILTER_OP_GT_S64_DOUBLE
] = &&LABEL_FILTER_OP_GT_S64_DOUBLE
,
307 [ FILTER_OP_LT_S64_DOUBLE
] = &&LABEL_FILTER_OP_LT_S64_DOUBLE
,
308 [ FILTER_OP_GE_S64_DOUBLE
] = &&LABEL_FILTER_OP_GE_S64_DOUBLE
,
309 [ FILTER_OP_LE_S64_DOUBLE
] = &&LABEL_FILTER_OP_LE_S64_DOUBLE
,
312 [ FILTER_OP_UNARY_PLUS
] = &&LABEL_FILTER_OP_UNARY_PLUS
,
313 [ FILTER_OP_UNARY_MINUS
] = &&LABEL_FILTER_OP_UNARY_MINUS
,
314 [ FILTER_OP_UNARY_NOT
] = &&LABEL_FILTER_OP_UNARY_NOT
,
315 [ FILTER_OP_UNARY_PLUS_S64
] = &&LABEL_FILTER_OP_UNARY_PLUS_S64
,
316 [ FILTER_OP_UNARY_MINUS_S64
] = &&LABEL_FILTER_OP_UNARY_MINUS_S64
,
317 [ FILTER_OP_UNARY_NOT_S64
] = &&LABEL_FILTER_OP_UNARY_NOT_S64
,
318 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE
,
319 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE
,
320 [ FILTER_OP_UNARY_NOT_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE
,
323 [ FILTER_OP_AND
] = &&LABEL_FILTER_OP_AND
,
324 [ FILTER_OP_OR
] = &&LABEL_FILTER_OP_OR
,
327 [ FILTER_OP_LOAD_FIELD_REF
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF
,
328 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING
,
329 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE
,
330 [ FILTER_OP_LOAD_FIELD_REF_S64
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64
,
331 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE
,
333 /* load from immediate operand */
334 [ FILTER_OP_LOAD_STRING
] = &&LABEL_FILTER_OP_LOAD_STRING
,
335 [ FILTER_OP_LOAD_STAR_GLOB_STRING
] = &&LABEL_FILTER_OP_LOAD_STAR_GLOB_STRING
,
336 [ FILTER_OP_LOAD_S64
] = &&LABEL_FILTER_OP_LOAD_S64
,
337 [ FILTER_OP_LOAD_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_DOUBLE
,
340 [ FILTER_OP_CAST_TO_S64
] = &&LABEL_FILTER_OP_CAST_TO_S64
,
341 [ FILTER_OP_CAST_DOUBLE_TO_S64
] = &&LABEL_FILTER_OP_CAST_DOUBLE_TO_S64
,
342 [ FILTER_OP_CAST_NOP
] = &&LABEL_FILTER_OP_CAST_NOP
,
344 /* get context ref */
345 [ FILTER_OP_GET_CONTEXT_REF
] = &&LABEL_FILTER_OP_GET_CONTEXT_REF
,
346 [ FILTER_OP_GET_CONTEXT_REF_STRING
] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_STRING
,
347 [ FILTER_OP_GET_CONTEXT_REF_S64
] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_S64
,
348 [ FILTER_OP_GET_CONTEXT_REF_DOUBLE
] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_DOUBLE
,
350 #endif /* #ifndef INTERPRETER_USE_SWITCH */
354 OP(FILTER_OP_UNKNOWN
):
355 OP(FILTER_OP_LOAD_FIELD_REF
):
356 #ifdef INTERPRETER_USE_SWITCH
358 #endif /* INTERPRETER_USE_SWITCH */
359 ERR("unknown bytecode op %u\n",
360 (unsigned int) *(filter_opcode_t
*) pc
);
364 OP(FILTER_OP_RETURN
):
365 /* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */
366 retval
= !!estack_ax_v
;
376 OP(FILTER_OP_RSHIFT
):
377 OP(FILTER_OP_LSHIFT
):
378 OP(FILTER_OP_BIN_AND
):
379 OP(FILTER_OP_BIN_OR
):
380 OP(FILTER_OP_BIN_XOR
):
381 ERR("unsupported bytecode op %u\n",
382 (unsigned int) *(filter_opcode_t
*) pc
);
388 /* Dynamic typing. */
389 switch (estack_ax_t
) {
391 switch (estack_bx_t
) {
393 JUMP_TO(FILTER_OP_EQ_S64
);
395 JUMP_TO(FILTER_OP_EQ_DOUBLE_S64
);
396 case REG_STRING
: /* Fall-through */
397 case REG_STAR_GLOB_STRING
:
401 ERR("Unknown filter register type (%d)",
408 switch (estack_bx_t
) {
410 JUMP_TO(FILTER_OP_EQ_S64_DOUBLE
);
412 JUMP_TO(FILTER_OP_EQ_DOUBLE
);
413 case REG_STRING
: /* Fall-through */
414 case REG_STAR_GLOB_STRING
:
418 ERR("Unknown filter register type (%d)",
425 switch (estack_bx_t
) {
426 case REG_S64
: /* Fall-through */
431 JUMP_TO(FILTER_OP_EQ_STRING
);
432 case REG_STAR_GLOB_STRING
:
433 JUMP_TO(FILTER_OP_EQ_STAR_GLOB_STRING
);
435 ERR("Unknown filter register type (%d)",
441 case REG_STAR_GLOB_STRING
:
442 switch (estack_bx_t
) {
443 case REG_S64
: /* Fall-through */
448 JUMP_TO(FILTER_OP_EQ_STAR_GLOB_STRING
);
449 case REG_STAR_GLOB_STRING
:
453 ERR("Unknown filter register type (%d)",
460 ERR("Unknown filter register type (%d)",
468 /* Dynamic typing. */
469 switch (estack_ax_t
) {
471 switch (estack_bx_t
) {
473 JUMP_TO(FILTER_OP_NE_S64
);
475 JUMP_TO(FILTER_OP_NE_DOUBLE_S64
);
476 case REG_STRING
: /* Fall-through */
477 case REG_STAR_GLOB_STRING
:
481 ERR("Unknown filter register type (%d)",
488 switch (estack_bx_t
) {
490 JUMP_TO(FILTER_OP_NE_S64_DOUBLE
);
492 JUMP_TO(FILTER_OP_NE_DOUBLE
);
493 case REG_STRING
: /* Fall-through */
494 case REG_STAR_GLOB_STRING
:
498 ERR("Unknown filter register type (%d)",
505 switch (estack_bx_t
) {
506 case REG_S64
: /* Fall-through */
511 JUMP_TO(FILTER_OP_NE_STRING
);
512 case REG_STAR_GLOB_STRING
:
513 JUMP_TO(FILTER_OP_NE_STAR_GLOB_STRING
);
515 ERR("Unknown filter register type (%d)",
521 case REG_STAR_GLOB_STRING
:
522 switch (estack_bx_t
) {
523 case REG_S64
: /* Fall-through */
528 JUMP_TO(FILTER_OP_NE_STAR_GLOB_STRING
);
529 case REG_STAR_GLOB_STRING
:
533 ERR("Unknown filter register type (%d)",
540 ERR("Unknown filter register type (%d)",
548 /* Dynamic typing. */
549 switch (estack_ax_t
) {
551 switch (estack_bx_t
) {
553 JUMP_TO(FILTER_OP_GT_S64
);
555 JUMP_TO(FILTER_OP_GT_DOUBLE_S64
);
556 case REG_STRING
: /* Fall-through */
557 case REG_STAR_GLOB_STRING
:
561 ERR("Unknown filter register type (%d)",
568 switch (estack_bx_t
) {
570 JUMP_TO(FILTER_OP_GT_S64_DOUBLE
);
572 JUMP_TO(FILTER_OP_GT_DOUBLE
);
573 case REG_STRING
: /* Fall-through */
574 case REG_STAR_GLOB_STRING
:
578 ERR("Unknown filter register type (%d)",
585 switch (estack_bx_t
) {
586 case REG_S64
: /* Fall-through */
587 case REG_DOUBLE
: /* Fall-through */
588 case REG_STAR_GLOB_STRING
:
592 JUMP_TO(FILTER_OP_GT_STRING
);
594 ERR("Unknown filter register type (%d)",
601 ERR("Unknown filter register type (%d)",
609 /* Dynamic typing. */
610 switch (estack_ax_t
) {
612 switch (estack_bx_t
) {
614 JUMP_TO(FILTER_OP_LT_S64
);
616 JUMP_TO(FILTER_OP_LT_DOUBLE_S64
);
617 case REG_STRING
: /* Fall-through */
618 case REG_STAR_GLOB_STRING
:
622 ERR("Unknown filter register type (%d)",
629 switch (estack_bx_t
) {
631 JUMP_TO(FILTER_OP_LT_S64_DOUBLE
);
633 JUMP_TO(FILTER_OP_LT_DOUBLE
);
634 case REG_STRING
: /* Fall-through */
635 case REG_STAR_GLOB_STRING
:
639 ERR("Unknown filter register type (%d)",
646 switch (estack_bx_t
) {
647 case REG_S64
: /* Fall-through */
648 case REG_DOUBLE
: /* Fall-through */
649 case REG_STAR_GLOB_STRING
:
653 JUMP_TO(FILTER_OP_LT_STRING
);
655 ERR("Unknown filter register type (%d)",
662 ERR("Unknown filter register type (%d)",
670 /* Dynamic typing. */
671 switch (estack_ax_t
) {
673 switch (estack_bx_t
) {
675 JUMP_TO(FILTER_OP_GE_S64
);
677 JUMP_TO(FILTER_OP_GE_DOUBLE_S64
);
678 case REG_STRING
: /* Fall-through */
679 case REG_STAR_GLOB_STRING
:
683 ERR("Unknown filter register type (%d)",
690 switch (estack_bx_t
) {
692 JUMP_TO(FILTER_OP_GE_S64_DOUBLE
);
694 JUMP_TO(FILTER_OP_GE_DOUBLE
);
695 case REG_STRING
: /* Fall-through */
696 case REG_STAR_GLOB_STRING
:
700 ERR("Unknown filter register type (%d)",
707 switch (estack_bx_t
) {
708 case REG_S64
: /* Fall-through */
709 case REG_DOUBLE
: /* Fall-through */
710 case REG_STAR_GLOB_STRING
:
714 JUMP_TO(FILTER_OP_GE_STRING
);
716 ERR("Unknown filter register type (%d)",
723 ERR("Unknown filter register type (%d)",
731 /* Dynamic typing. */
732 switch (estack_ax_t
) {
734 switch (estack_bx_t
) {
736 JUMP_TO(FILTER_OP_LE_S64
);
738 JUMP_TO(FILTER_OP_LE_DOUBLE_S64
);
739 case REG_STRING
: /* Fall-through */
740 case REG_STAR_GLOB_STRING
:
744 ERR("Unknown filter register type (%d)",
751 switch (estack_bx_t
) {
753 JUMP_TO(FILTER_OP_LE_S64_DOUBLE
);
755 JUMP_TO(FILTER_OP_LE_DOUBLE
);
756 case REG_STRING
: /* Fall-through */
757 case REG_STAR_GLOB_STRING
:
761 ERR("Unknown filter register type (%d)",
768 switch (estack_bx_t
) {
769 case REG_S64
: /* Fall-through */
770 case REG_DOUBLE
: /* Fall-through */
771 case REG_STAR_GLOB_STRING
:
775 JUMP_TO(FILTER_OP_LE_STRING
);
777 ERR("Unknown filter register type (%d)",
784 ERR("Unknown filter register type (%d)",
791 OP(FILTER_OP_EQ_STRING
):
795 res
= (stack_strcmp(stack
, top
, "==") == 0);
796 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
798 estack_ax_t
= REG_S64
;
799 next_pc
+= sizeof(struct binary_op
);
802 OP(FILTER_OP_NE_STRING
):
806 res
= (stack_strcmp(stack
, top
, "!=") != 0);
807 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
809 estack_ax_t
= REG_S64
;
810 next_pc
+= sizeof(struct binary_op
);
813 OP(FILTER_OP_GT_STRING
):
817 res
= (stack_strcmp(stack
, top
, ">") > 0);
818 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
820 estack_ax_t
= REG_S64
;
821 next_pc
+= sizeof(struct binary_op
);
824 OP(FILTER_OP_LT_STRING
):
828 res
= (stack_strcmp(stack
, top
, "<") < 0);
829 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
831 estack_ax_t
= REG_S64
;
832 next_pc
+= sizeof(struct binary_op
);
835 OP(FILTER_OP_GE_STRING
):
839 res
= (stack_strcmp(stack
, top
, ">=") >= 0);
840 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
842 estack_ax_t
= REG_S64
;
843 next_pc
+= sizeof(struct binary_op
);
846 OP(FILTER_OP_LE_STRING
):
850 res
= (stack_strcmp(stack
, top
, "<=") <= 0);
851 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
853 estack_ax_t
= REG_S64
;
854 next_pc
+= sizeof(struct binary_op
);
858 OP(FILTER_OP_EQ_STAR_GLOB_STRING
):
862 res
= (stack_star_glob_match(stack
, top
, "==") == 0);
863 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
865 estack_ax_t
= REG_S64
;
866 next_pc
+= sizeof(struct binary_op
);
869 OP(FILTER_OP_NE_STAR_GLOB_STRING
):
873 res
= (stack_star_glob_match(stack
, top
, "!=") != 0);
874 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
876 estack_ax_t
= REG_S64
;
877 next_pc
+= sizeof(struct binary_op
);
881 OP(FILTER_OP_EQ_S64
):
885 res
= (estack_bx_v
== estack_ax_v
);
886 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
888 estack_ax_t
= REG_S64
;
889 next_pc
+= sizeof(struct binary_op
);
892 OP(FILTER_OP_NE_S64
):
896 res
= (estack_bx_v
!= estack_ax_v
);
897 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
899 estack_ax_t
= REG_S64
;
900 next_pc
+= sizeof(struct binary_op
);
903 OP(FILTER_OP_GT_S64
):
907 res
= (estack_bx_v
> estack_ax_v
);
908 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
910 estack_ax_t
= REG_S64
;
911 next_pc
+= sizeof(struct binary_op
);
914 OP(FILTER_OP_LT_S64
):
918 res
= (estack_bx_v
< estack_ax_v
);
919 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
921 estack_ax_t
= REG_S64
;
922 next_pc
+= sizeof(struct binary_op
);
925 OP(FILTER_OP_GE_S64
):
929 res
= (estack_bx_v
>= estack_ax_v
);
930 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
932 estack_ax_t
= REG_S64
;
933 next_pc
+= sizeof(struct binary_op
);
936 OP(FILTER_OP_LE_S64
):
940 res
= (estack_bx_v
<= estack_ax_v
);
941 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
943 estack_ax_t
= REG_S64
;
944 next_pc
+= sizeof(struct binary_op
);
948 OP(FILTER_OP_EQ_DOUBLE
):
952 res
= (estack_bx(stack
, top
)->u
.d
== estack_ax(stack
, top
)->u
.d
);
953 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
955 estack_ax_t
= REG_S64
;
956 next_pc
+= sizeof(struct binary_op
);
959 OP(FILTER_OP_NE_DOUBLE
):
963 res
= (estack_bx(stack
, top
)->u
.d
!= estack_ax(stack
, top
)->u
.d
);
964 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
966 estack_ax_t
= REG_S64
;
967 next_pc
+= sizeof(struct binary_op
);
970 OP(FILTER_OP_GT_DOUBLE
):
974 res
= (estack_bx(stack
, top
)->u
.d
> estack_ax(stack
, top
)->u
.d
);
975 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
977 estack_ax_t
= REG_S64
;
978 next_pc
+= sizeof(struct binary_op
);
981 OP(FILTER_OP_LT_DOUBLE
):
985 res
= (estack_bx(stack
, top
)->u
.d
< estack_ax(stack
, top
)->u
.d
);
986 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
988 estack_ax_t
= REG_S64
;
989 next_pc
+= sizeof(struct binary_op
);
992 OP(FILTER_OP_GE_DOUBLE
):
996 res
= (estack_bx(stack
, top
)->u
.d
>= estack_ax(stack
, top
)->u
.d
);
997 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
999 estack_ax_t
= REG_S64
;
1000 next_pc
+= sizeof(struct binary_op
);
1003 OP(FILTER_OP_LE_DOUBLE
):
1007 res
= (estack_bx(stack
, top
)->u
.d
<= estack_ax(stack
, top
)->u
.d
);
1008 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1010 estack_ax_t
= REG_S64
;
1011 next_pc
+= sizeof(struct binary_op
);
1015 /* Mixed S64-double binary comparators */
1016 OP(FILTER_OP_EQ_DOUBLE_S64
):
1020 res
= (estack_bx(stack
, top
)->u
.d
== estack_ax_v
);
1021 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1023 estack_ax_t
= REG_S64
;
1024 next_pc
+= sizeof(struct binary_op
);
1027 OP(FILTER_OP_NE_DOUBLE_S64
):
1031 res
= (estack_bx(stack
, top
)->u
.d
!= estack_ax_v
);
1032 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1034 estack_ax_t
= REG_S64
;
1035 next_pc
+= sizeof(struct binary_op
);
1038 OP(FILTER_OP_GT_DOUBLE_S64
):
1042 res
= (estack_bx(stack
, top
)->u
.d
> estack_ax_v
);
1043 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1045 estack_ax_t
= REG_S64
;
1046 next_pc
+= sizeof(struct binary_op
);
1049 OP(FILTER_OP_LT_DOUBLE_S64
):
1053 res
= (estack_bx(stack
, top
)->u
.d
< estack_ax_v
);
1054 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1056 estack_ax_t
= REG_S64
;
1057 next_pc
+= sizeof(struct binary_op
);
1060 OP(FILTER_OP_GE_DOUBLE_S64
):
1064 res
= (estack_bx(stack
, top
)->u
.d
>= estack_ax_v
);
1065 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1067 estack_ax_t
= REG_S64
;
1068 next_pc
+= sizeof(struct binary_op
);
1071 OP(FILTER_OP_LE_DOUBLE_S64
):
1075 res
= (estack_bx(stack
, top
)->u
.d
<= estack_ax_v
);
1076 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1078 estack_ax_t
= REG_S64
;
1079 next_pc
+= sizeof(struct binary_op
);
1083 OP(FILTER_OP_EQ_S64_DOUBLE
):
1087 res
= (estack_bx_v
== estack_ax(stack
, top
)->u
.d
);
1088 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1090 estack_ax_t
= REG_S64
;
1091 next_pc
+= sizeof(struct binary_op
);
1094 OP(FILTER_OP_NE_S64_DOUBLE
):
1098 res
= (estack_bx_v
!= estack_ax(stack
, top
)->u
.d
);
1099 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1101 estack_ax_t
= REG_S64
;
1102 next_pc
+= sizeof(struct binary_op
);
1105 OP(FILTER_OP_GT_S64_DOUBLE
):
1109 res
= (estack_bx_v
> estack_ax(stack
, top
)->u
.d
);
1110 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1112 estack_ax_t
= REG_S64
;
1113 next_pc
+= sizeof(struct binary_op
);
1116 OP(FILTER_OP_LT_S64_DOUBLE
):
1120 res
= (estack_bx_v
< estack_ax(stack
, top
)->u
.d
);
1121 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1123 estack_ax_t
= REG_S64
;
1124 next_pc
+= sizeof(struct binary_op
);
1127 OP(FILTER_OP_GE_S64_DOUBLE
):
1131 res
= (estack_bx_v
>= estack_ax(stack
, top
)->u
.d
);
1132 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1134 estack_ax_t
= REG_S64
;
1135 next_pc
+= sizeof(struct binary_op
);
1138 OP(FILTER_OP_LE_S64_DOUBLE
):
1142 res
= (estack_bx_v
<= estack_ax(stack
, top
)->u
.d
);
1143 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1145 estack_ax_t
= REG_S64
;
1146 next_pc
+= sizeof(struct binary_op
);
1151 OP(FILTER_OP_UNARY_PLUS
):
1153 /* Dynamic typing. */
1154 switch (estack_ax_t
) {
1155 case REG_S64
: /* Fall-through. */
1156 JUMP_TO(FILTER_OP_UNARY_PLUS_S64
);
1158 JUMP_TO(FILTER_OP_UNARY_PLUS_DOUBLE
);
1159 case REG_STRING
: /* Fall-through */
1160 case REG_STAR_GLOB_STRING
:
1164 ERR("Unknown filter register type (%d)",
1170 OP(FILTER_OP_UNARY_MINUS
):
1172 /* Dynamic typing. */
1173 switch (estack_ax_t
) {
1175 JUMP_TO(FILTER_OP_UNARY_MINUS_S64
);
1177 JUMP_TO(FILTER_OP_UNARY_MINUS_DOUBLE
);
1178 case REG_STRING
: /* Fall-through */
1179 case REG_STAR_GLOB_STRING
:
1183 ERR("Unknown filter register type (%d)",
1189 OP(FILTER_OP_UNARY_NOT
):
1191 /* Dynamic typing. */
1192 switch (estack_ax_t
) {
1194 JUMP_TO(FILTER_OP_UNARY_NOT_S64
);
1196 JUMP_TO(FILTER_OP_UNARY_NOT_DOUBLE
);
1197 case REG_STRING
: /* Fall-through */
1198 case REG_STAR_GLOB_STRING
:
1202 ERR("Unknown filter register type (%d)",
1207 next_pc
+= sizeof(struct unary_op
);
1211 OP(FILTER_OP_UNARY_PLUS_S64
):
1212 OP(FILTER_OP_UNARY_PLUS_DOUBLE
):
1214 next_pc
+= sizeof(struct unary_op
);
1217 OP(FILTER_OP_UNARY_MINUS_S64
):
1219 estack_ax_v
= -estack_ax_v
;
1220 next_pc
+= sizeof(struct unary_op
);
1223 OP(FILTER_OP_UNARY_MINUS_DOUBLE
):
1225 estack_ax(stack
, top
)->u
.d
= -estack_ax(stack
, top
)->u
.d
;
1226 next_pc
+= sizeof(struct unary_op
);
1229 OP(FILTER_OP_UNARY_NOT_S64
):
1231 estack_ax_v
= !estack_ax_v
;
1232 next_pc
+= sizeof(struct unary_op
);
1235 OP(FILTER_OP_UNARY_NOT_DOUBLE
):
1237 estack_ax_v
= !estack_ax(stack
, top
)->u
.d
;
1238 estack_ax_t
= REG_S64
;
1239 next_pc
+= sizeof(struct unary_op
);
1246 struct logical_op
*insn
= (struct logical_op
*) pc
;
1248 if (estack_ax_t
!= REG_S64
) {
1252 /* If AX is 0, skip and evaluate to 0 */
1253 if (unlikely(estack_ax_v
== 0)) {
1254 dbg_printf("Jumping to bytecode offset %u\n",
1255 (unsigned int) insn
->skip_offset
);
1256 next_pc
= start_pc
+ insn
->skip_offset
;
1258 /* Pop 1 when jump not taken */
1259 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1260 next_pc
+= sizeof(struct logical_op
);
1266 struct logical_op
*insn
= (struct logical_op
*) pc
;
1268 if (estack_ax_t
!= REG_S64
) {
1272 /* If AX is nonzero, skip and evaluate to 1 */
1273 if (unlikely(estack_ax_v
!= 0)) {
1275 dbg_printf("Jumping to bytecode offset %u\n",
1276 (unsigned int) insn
->skip_offset
);
1277 next_pc
= start_pc
+ insn
->skip_offset
;
1279 /* Pop 1 when jump not taken */
1280 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1281 next_pc
+= sizeof(struct logical_op
);
1287 /* load field ref */
1288 OP(FILTER_OP_LOAD_FIELD_REF_STRING
):
1290 struct load_op
*insn
= (struct load_op
*) pc
;
1291 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1293 dbg_printf("load field ref offset %u type string\n",
1295 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1296 estack_ax(stack
, top
)->u
.s
.str
=
1297 *(const char * const *) &filter_stack_data
[ref
->offset
];
1298 if (unlikely(!estack_ax(stack
, top
)->u
.s
.str
)) {
1299 dbg_printf("Filter warning: loading a NULL string.\n");
1303 estack_ax(stack
, top
)->u
.s
.seq_len
= UINT_MAX
;
1304 estack_ax(stack
, top
)->u
.s
.literal_type
=
1305 ESTACK_STRING_LITERAL_TYPE_NONE
;
1306 estack_ax_t
= REG_STRING
;
1307 dbg_printf("ref load string %s\n", estack_ax(stack
, top
)->u
.s
.str
);
1308 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1312 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE
):
1314 struct load_op
*insn
= (struct load_op
*) pc
;
1315 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1317 dbg_printf("load field ref offset %u type sequence\n",
1319 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1320 estack_ax(stack
, top
)->u
.s
.seq_len
=
1321 *(unsigned long *) &filter_stack_data
[ref
->offset
];
1322 estack_ax(stack
, top
)->u
.s
.str
=
1323 *(const char **) (&filter_stack_data
[ref
->offset
1324 + sizeof(unsigned long)]);
1325 estack_ax_t
= REG_STRING
;
1326 if (unlikely(!estack_ax(stack
, top
)->u
.s
.str
)) {
1327 dbg_printf("Filter warning: loading a NULL sequence.\n");
1331 estack_ax(stack
, top
)->u
.s
.literal_type
=
1332 ESTACK_STRING_LITERAL_TYPE_NONE
;
1333 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1337 OP(FILTER_OP_LOAD_FIELD_REF_S64
):
1339 struct load_op
*insn
= (struct load_op
*) pc
;
1340 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1342 dbg_printf("load field ref offset %u type s64\n",
1344 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1346 ((struct literal_numeric
*) &filter_stack_data
[ref
->offset
])->v
;
1347 estack_ax_t
= REG_S64
;
1348 dbg_printf("ref load s64 %" PRIi64
"\n", estack_ax_v
);
1349 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1353 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE
):
1355 struct load_op
*insn
= (struct load_op
*) pc
;
1356 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1358 dbg_printf("load field ref offset %u type double\n",
1360 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1361 memcpy(&estack_ax(stack
, top
)->u
.d
, &filter_stack_data
[ref
->offset
],
1362 sizeof(struct literal_double
));
1363 estack_ax_t
= REG_DOUBLE
;
1364 dbg_printf("ref load double %g\n", estack_ax(stack
, top
)->u
.d
);
1365 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1369 /* load from immediate operand */
1370 OP(FILTER_OP_LOAD_STRING
):
1372 struct load_op
*insn
= (struct load_op
*) pc
;
1374 dbg_printf("load string %s\n", insn
->data
);
1375 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1376 estack_ax(stack
, top
)->u
.s
.str
= insn
->data
;
1377 estack_ax(stack
, top
)->u
.s
.seq_len
= UINT_MAX
;
1378 estack_ax(stack
, top
)->u
.s
.literal_type
=
1379 ESTACK_STRING_LITERAL_TYPE_PLAIN
;
1380 estack_ax_t
= REG_STRING
;
1381 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1385 OP(FILTER_OP_LOAD_STAR_GLOB_STRING
):
1387 struct load_op
*insn
= (struct load_op
*) pc
;
1389 dbg_printf("load globbing pattern %s\n", insn
->data
);
1390 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1391 estack_ax(stack
, top
)->u
.s
.str
= insn
->data
;
1392 estack_ax(stack
, top
)->u
.s
.seq_len
= UINT_MAX
;
1393 estack_ax(stack
, top
)->u
.s
.literal_type
=
1394 ESTACK_STRING_LITERAL_TYPE_STAR_GLOB
;
1395 estack_ax_t
= REG_STAR_GLOB_STRING
;
1396 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1400 OP(FILTER_OP_LOAD_S64
):
1402 struct load_op
*insn
= (struct load_op
*) pc
;
1404 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1405 estack_ax_v
= ((struct literal_numeric
*) insn
->data
)->v
;
1406 estack_ax_t
= REG_S64
;
1407 dbg_printf("load s64 %" PRIi64
"\n", estack_ax_v
);
1408 next_pc
+= sizeof(struct load_op
)
1409 + sizeof(struct literal_numeric
);
1413 OP(FILTER_OP_LOAD_DOUBLE
):
1415 struct load_op
*insn
= (struct load_op
*) pc
;
1417 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1418 memcpy(&estack_ax(stack
, top
)->u
.d
, insn
->data
,
1419 sizeof(struct literal_double
));
1420 estack_ax_t
= REG_DOUBLE
;
1421 dbg_printf("load double %g\n", estack_ax(stack
, top
)->u
.d
);
1422 next_pc
+= sizeof(struct load_op
)
1423 + sizeof(struct literal_double
);
1428 OP(FILTER_OP_CAST_TO_S64
):
1430 /* Dynamic typing. */
1431 switch (estack_ax_t
) {
1433 JUMP_TO(FILTER_OP_CAST_NOP
);
1435 JUMP_TO(FILTER_OP_CAST_DOUBLE_TO_S64
);
1436 case REG_STRING
: /* Fall-through */
1437 case REG_STAR_GLOB_STRING
:
1441 ERR("Unknown filter register type (%d)",
1448 OP(FILTER_OP_CAST_DOUBLE_TO_S64
):
1450 estack_ax_v
= (int64_t) estack_ax(stack
, top
)->u
.d
;
1451 estack_ax_t
= REG_S64
;
1452 next_pc
+= sizeof(struct cast_op
);
1456 OP(FILTER_OP_CAST_NOP
):
1458 next_pc
+= sizeof(struct cast_op
);
1462 /* get context ref */
1463 OP(FILTER_OP_GET_CONTEXT_REF
):
1465 struct load_op
*insn
= (struct load_op
*) pc
;
1466 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1467 struct lttng_ctx
*ctx
;
1468 struct lttng_ctx_field
*ctx_field
;
1469 struct lttng_ctx_value v
;
1471 dbg_printf("get context ref offset %u type dynamic\n",
1473 ctx
= rcu_dereference(session
->ctx
);
1474 ctx_field
= &ctx
->fields
[ref
->offset
];
1475 ctx_field
->get_value(ctx_field
, &v
);
1476 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1478 case LTTNG_UST_DYNAMIC_TYPE_NONE
:
1481 case LTTNG_UST_DYNAMIC_TYPE_S64
:
1482 estack_ax_v
= v
.u
.s64
;
1483 estack_ax_t
= REG_S64
;
1484 dbg_printf("ref get context dynamic s64 %" PRIi64
"\n", estack_ax_v
);
1486 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE
:
1487 estack_ax(stack
, top
)->u
.d
= v
.u
.d
;
1488 estack_ax_t
= REG_DOUBLE
;
1489 dbg_printf("ref get context dynamic double %g\n", estack_ax(stack
, top
)->u
.d
);
1491 case LTTNG_UST_DYNAMIC_TYPE_STRING
:
1492 estack_ax(stack
, top
)->u
.s
.str
= v
.u
.str
;
1493 if (unlikely(!estack_ax(stack
, top
)->u
.s
.str
)) {
1494 dbg_printf("Filter warning: loading a NULL string.\n");
1498 estack_ax(stack
, top
)->u
.s
.seq_len
= UINT_MAX
;
1499 estack_ax(stack
, top
)->u
.s
.literal_type
=
1500 ESTACK_STRING_LITERAL_TYPE_NONE
;
1501 dbg_printf("ref get context dynamic string %s\n", estack_ax(stack
, top
)->u
.s
.str
);
1502 estack_ax_t
= REG_STRING
;
1505 dbg_printf("Filter warning: unknown dynamic type (%d).\n", (int) v
.sel
);
1509 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1513 OP(FILTER_OP_GET_CONTEXT_REF_STRING
):
1515 struct load_op
*insn
= (struct load_op
*) pc
;
1516 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1517 struct lttng_ctx
*ctx
;
1518 struct lttng_ctx_field
*ctx_field
;
1519 struct lttng_ctx_value v
;
1521 dbg_printf("get context ref offset %u type string\n",
1523 ctx
= rcu_dereference(session
->ctx
);
1524 ctx_field
= &ctx
->fields
[ref
->offset
];
1525 ctx_field
->get_value(ctx_field
, &v
);
1526 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1527 estack_ax(stack
, top
)->u
.s
.str
= v
.u
.str
;
1528 if (unlikely(!estack_ax(stack
, top
)->u
.s
.str
)) {
1529 dbg_printf("Filter warning: loading a NULL string.\n");
1533 estack_ax(stack
, top
)->u
.s
.seq_len
= UINT_MAX
;
1534 estack_ax(stack
, top
)->u
.s
.literal_type
=
1535 ESTACK_STRING_LITERAL_TYPE_NONE
;
1536 estack_ax_t
= REG_STRING
;
1537 dbg_printf("ref get context string %s\n", estack_ax(stack
, top
)->u
.s
.str
);
1538 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1542 OP(FILTER_OP_GET_CONTEXT_REF_S64
):
1544 struct load_op
*insn
= (struct load_op
*) pc
;
1545 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1546 struct lttng_ctx
*ctx
;
1547 struct lttng_ctx_field
*ctx_field
;
1548 struct lttng_ctx_value v
;
1550 dbg_printf("get context ref offset %u type s64\n",
1552 ctx
= rcu_dereference(session
->ctx
);
1553 ctx_field
= &ctx
->fields
[ref
->offset
];
1554 ctx_field
->get_value(ctx_field
, &v
);
1555 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1556 estack_ax_v
= v
.u
.s64
;
1557 estack_ax_t
= REG_S64
;
1558 dbg_printf("ref get context s64 %" PRIi64
"\n", estack_ax_v
);
1559 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1563 OP(FILTER_OP_GET_CONTEXT_REF_DOUBLE
):
1565 struct load_op
*insn
= (struct load_op
*) pc
;
1566 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1567 struct lttng_ctx
*ctx
;
1568 struct lttng_ctx_field
*ctx_field
;
1569 struct lttng_ctx_value v
;
1571 dbg_printf("get context ref offset %u type double\n",
1573 ctx
= rcu_dereference(session
->ctx
);
1574 ctx_field
= &ctx
->fields
[ref
->offset
];
1575 ctx_field
->get_value(ctx_field
, &v
);
1576 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1577 memcpy(&estack_ax(stack
, top
)->u
.d
, &v
.u
.d
, sizeof(struct literal_double
));
1578 estack_ax_t
= REG_DOUBLE
;
1579 dbg_printf("ref get context double %g\n", estack_ax(stack
, top
)->u
.d
);
1580 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1586 /* return 0 (discard) on error */