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>
30 #include "lttng-filter.h"
31 #include "string-utils.h"
35 * -2: unknown escape char.
40 int parse_char(const char **p
)
60 * Returns SIZE_MAX if the string is null-terminated, or the number of
64 size_t get_str_or_seq_len(const struct estack_entry
*entry
)
66 return entry
->u
.s
.seq_len
;
70 int stack_star_glob_match(struct estack
*stack
, int top
, const char *cmp_type
)
73 const char *candidate
;
77 /* Find out which side is the pattern vs. the candidate. */
78 if (estack_ax(stack
, top
)->u
.s
.literal_type
== ESTACK_STRING_LITERAL_TYPE_STAR_GLOB
) {
79 pattern
= estack_ax(stack
, top
)->u
.s
.str
;
80 pattern_len
= get_str_or_seq_len(estack_ax(stack
, top
));
81 candidate
= estack_bx(stack
, top
)->u
.s
.str
;
82 candidate_len
= get_str_or_seq_len(estack_bx(stack
, top
));
84 pattern
= estack_bx(stack
, top
)->u
.s
.str
;
85 pattern_len
= get_str_or_seq_len(estack_bx(stack
, top
));
86 candidate
= estack_ax(stack
, top
)->u
.s
.str
;
87 candidate_len
= get_str_or_seq_len(estack_ax(stack
, top
));
90 /* Perform the match. Returns 0 when the result is true. */
91 return !strutils_star_glob_match(pattern
, pattern_len
, candidate
,
96 int stack_strcmp(struct estack
*stack
, int top
, const char *cmp_type
)
98 const char *p
= estack_bx(stack
, top
)->u
.s
.str
, *q
= estack_ax(stack
, top
)->u
.s
.str
;
105 if (unlikely(p
- estack_bx(stack
, top
)->u
.s
.str
>= estack_bx(stack
, top
)->u
.s
.seq_len
|| *p
== '\0')) {
106 if (q
- estack_ax(stack
, top
)->u
.s
.str
>= estack_ax(stack
, top
)->u
.s
.seq_len
|| *q
== '\0') {
109 if (estack_ax(stack
, top
)->u
.s
.literal_type
==
110 ESTACK_STRING_LITERAL_TYPE_PLAIN
) {
111 ret
= parse_char(&q
);
118 if (unlikely(q
- estack_ax(stack
, top
)->u
.s
.str
>= estack_ax(stack
, top
)->u
.s
.seq_len
|| *q
== '\0')) {
119 if (estack_bx(stack
, top
)->u
.s
.literal_type
==
120 ESTACK_STRING_LITERAL_TYPE_PLAIN
) {
121 ret
= parse_char(&p
);
127 if (estack_bx(stack
, top
)->u
.s
.literal_type
==
128 ESTACK_STRING_LITERAL_TYPE_PLAIN
) {
129 ret
= parse_char(&p
);
132 } else if (ret
== -2) {
135 /* else compare both char */
137 if (estack_ax(stack
, top
)->u
.s
.literal_type
==
138 ESTACK_STRING_LITERAL_TYPE_PLAIN
) {
139 ret
= parse_char(&q
);
142 } else if (ret
== -2) {
162 uint64_t lttng_filter_false(void *filter_data
,
163 const char *filter_stack_data
)
168 #ifdef INTERPRETER_USE_SWITCH
171 * Fallback for compilers that do not support taking address of labels.
175 start_pc = &bytecode->data[0]; \
176 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
178 dbg_printf("Executing op %s (%u)\n", \
179 print_op((unsigned int) *(filter_opcode_t *) pc), \
180 (unsigned int) *(filter_opcode_t *) pc); \
181 switch (*(filter_opcode_t *) pc) {
183 #define OP(name) jump_target_##name: __attribute__((unused)); \
191 #define JUMP_TO(name) \
192 goto jump_target_##name
197 * Dispatch-table based interpreter.
201 start_pc = &bytecode->data[0]; \
202 pc = next_pc = start_pc; \
203 if (unlikely(pc - start_pc >= bytecode->len)) \
205 goto *dispatch[*(filter_opcode_t *) pc];
212 goto *dispatch[*(filter_opcode_t *) pc];
216 #define JUMP_TO(name) \
222 * Return 0 (discard), or raise the 0x1 flag (log event).
223 * Currently, other flags are kept for future extensions and have no
226 uint64_t lttng_filter_interpret_bytecode(void *filter_data
,
227 const char *filter_stack_data
)
229 struct bytecode_runtime
*bytecode
= filter_data
;
230 struct lttng_session
*session
= bytecode
->p
.session
;
231 void *pc
, *next_pc
, *start_pc
;
234 struct estack _stack
;
235 struct estack
*stack
= &_stack
;
236 register int64_t ax
= 0, bx
= 0;
237 register enum entry_type ax_t
= REG_UNKNOWN
, bx_t
= REG_UNKNOWN
;
238 register int top
= FILTER_STACK_EMPTY
;
239 #ifndef INTERPRETER_USE_SWITCH
240 static void *dispatch
[NR_FILTER_OPS
] = {
241 [ FILTER_OP_UNKNOWN
] = &&LABEL_FILTER_OP_UNKNOWN
,
243 [ FILTER_OP_RETURN
] = &&LABEL_FILTER_OP_RETURN
,
246 [ FILTER_OP_MUL
] = &&LABEL_FILTER_OP_MUL
,
247 [ FILTER_OP_DIV
] = &&LABEL_FILTER_OP_DIV
,
248 [ FILTER_OP_MOD
] = &&LABEL_FILTER_OP_MOD
,
249 [ FILTER_OP_PLUS
] = &&LABEL_FILTER_OP_PLUS
,
250 [ FILTER_OP_MINUS
] = &&LABEL_FILTER_OP_MINUS
,
251 [ FILTER_OP_RSHIFT
] = &&LABEL_FILTER_OP_RSHIFT
,
252 [ FILTER_OP_LSHIFT
] = &&LABEL_FILTER_OP_LSHIFT
,
253 [ FILTER_OP_BIN_AND
] = &&LABEL_FILTER_OP_BIN_AND
,
254 [ FILTER_OP_BIN_OR
] = &&LABEL_FILTER_OP_BIN_OR
,
255 [ FILTER_OP_BIN_XOR
] = &&LABEL_FILTER_OP_BIN_XOR
,
257 /* binary comparators */
258 [ FILTER_OP_EQ
] = &&LABEL_FILTER_OP_EQ
,
259 [ FILTER_OP_NE
] = &&LABEL_FILTER_OP_NE
,
260 [ FILTER_OP_GT
] = &&LABEL_FILTER_OP_GT
,
261 [ FILTER_OP_LT
] = &&LABEL_FILTER_OP_LT
,
262 [ FILTER_OP_GE
] = &&LABEL_FILTER_OP_GE
,
263 [ FILTER_OP_LE
] = &&LABEL_FILTER_OP_LE
,
265 /* string binary comparator */
266 [ FILTER_OP_EQ_STRING
] = &&LABEL_FILTER_OP_EQ_STRING
,
267 [ FILTER_OP_NE_STRING
] = &&LABEL_FILTER_OP_NE_STRING
,
268 [ FILTER_OP_GT_STRING
] = &&LABEL_FILTER_OP_GT_STRING
,
269 [ FILTER_OP_LT_STRING
] = &&LABEL_FILTER_OP_LT_STRING
,
270 [ FILTER_OP_GE_STRING
] = &&LABEL_FILTER_OP_GE_STRING
,
271 [ FILTER_OP_LE_STRING
] = &&LABEL_FILTER_OP_LE_STRING
,
273 /* globbing pattern binary comparator */
274 [ FILTER_OP_EQ_STAR_GLOB_STRING
] = &&LABEL_FILTER_OP_EQ_STAR_GLOB_STRING
,
275 [ FILTER_OP_NE_STAR_GLOB_STRING
] = &&LABEL_FILTER_OP_NE_STAR_GLOB_STRING
,
277 /* s64 binary comparator */
278 [ FILTER_OP_EQ_S64
] = &&LABEL_FILTER_OP_EQ_S64
,
279 [ FILTER_OP_NE_S64
] = &&LABEL_FILTER_OP_NE_S64
,
280 [ FILTER_OP_GT_S64
] = &&LABEL_FILTER_OP_GT_S64
,
281 [ FILTER_OP_LT_S64
] = &&LABEL_FILTER_OP_LT_S64
,
282 [ FILTER_OP_GE_S64
] = &&LABEL_FILTER_OP_GE_S64
,
283 [ FILTER_OP_LE_S64
] = &&LABEL_FILTER_OP_LE_S64
,
285 /* double binary comparator */
286 [ FILTER_OP_EQ_DOUBLE
] = &&LABEL_FILTER_OP_EQ_DOUBLE
,
287 [ FILTER_OP_NE_DOUBLE
] = &&LABEL_FILTER_OP_NE_DOUBLE
,
288 [ FILTER_OP_GT_DOUBLE
] = &&LABEL_FILTER_OP_GT_DOUBLE
,
289 [ FILTER_OP_LT_DOUBLE
] = &&LABEL_FILTER_OP_LT_DOUBLE
,
290 [ FILTER_OP_GE_DOUBLE
] = &&LABEL_FILTER_OP_GE_DOUBLE
,
291 [ FILTER_OP_LE_DOUBLE
] = &&LABEL_FILTER_OP_LE_DOUBLE
,
293 /* Mixed S64-double binary comparators */
294 [ FILTER_OP_EQ_DOUBLE_S64
] = &&LABEL_FILTER_OP_EQ_DOUBLE_S64
,
295 [ FILTER_OP_NE_DOUBLE_S64
] = &&LABEL_FILTER_OP_NE_DOUBLE_S64
,
296 [ FILTER_OP_GT_DOUBLE_S64
] = &&LABEL_FILTER_OP_GT_DOUBLE_S64
,
297 [ FILTER_OP_LT_DOUBLE_S64
] = &&LABEL_FILTER_OP_LT_DOUBLE_S64
,
298 [ FILTER_OP_GE_DOUBLE_S64
] = &&LABEL_FILTER_OP_GE_DOUBLE_S64
,
299 [ FILTER_OP_LE_DOUBLE_S64
] = &&LABEL_FILTER_OP_LE_DOUBLE_S64
,
301 [ FILTER_OP_EQ_S64_DOUBLE
] = &&LABEL_FILTER_OP_EQ_S64_DOUBLE
,
302 [ FILTER_OP_NE_S64_DOUBLE
] = &&LABEL_FILTER_OP_NE_S64_DOUBLE
,
303 [ FILTER_OP_GT_S64_DOUBLE
] = &&LABEL_FILTER_OP_GT_S64_DOUBLE
,
304 [ FILTER_OP_LT_S64_DOUBLE
] = &&LABEL_FILTER_OP_LT_S64_DOUBLE
,
305 [ FILTER_OP_GE_S64_DOUBLE
] = &&LABEL_FILTER_OP_GE_S64_DOUBLE
,
306 [ FILTER_OP_LE_S64_DOUBLE
] = &&LABEL_FILTER_OP_LE_S64_DOUBLE
,
309 [ FILTER_OP_UNARY_PLUS
] = &&LABEL_FILTER_OP_UNARY_PLUS
,
310 [ FILTER_OP_UNARY_MINUS
] = &&LABEL_FILTER_OP_UNARY_MINUS
,
311 [ FILTER_OP_UNARY_NOT
] = &&LABEL_FILTER_OP_UNARY_NOT
,
312 [ FILTER_OP_UNARY_PLUS_S64
] = &&LABEL_FILTER_OP_UNARY_PLUS_S64
,
313 [ FILTER_OP_UNARY_MINUS_S64
] = &&LABEL_FILTER_OP_UNARY_MINUS_S64
,
314 [ FILTER_OP_UNARY_NOT_S64
] = &&LABEL_FILTER_OP_UNARY_NOT_S64
,
315 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE
,
316 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE
,
317 [ FILTER_OP_UNARY_NOT_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE
,
320 [ FILTER_OP_AND
] = &&LABEL_FILTER_OP_AND
,
321 [ FILTER_OP_OR
] = &&LABEL_FILTER_OP_OR
,
324 [ FILTER_OP_LOAD_FIELD_REF
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF
,
325 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING
,
326 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE
,
327 [ FILTER_OP_LOAD_FIELD_REF_S64
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64
,
328 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE
,
330 /* load from immediate operand */
331 [ FILTER_OP_LOAD_STRING
] = &&LABEL_FILTER_OP_LOAD_STRING
,
332 [ FILTER_OP_LOAD_STAR_GLOB_STRING
] = &&LABEL_FILTER_OP_LOAD_STAR_GLOB_STRING
,
333 [ FILTER_OP_LOAD_S64
] = &&LABEL_FILTER_OP_LOAD_S64
,
334 [ FILTER_OP_LOAD_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_DOUBLE
,
337 [ FILTER_OP_CAST_TO_S64
] = &&LABEL_FILTER_OP_CAST_TO_S64
,
338 [ FILTER_OP_CAST_DOUBLE_TO_S64
] = &&LABEL_FILTER_OP_CAST_DOUBLE_TO_S64
,
339 [ FILTER_OP_CAST_NOP
] = &&LABEL_FILTER_OP_CAST_NOP
,
341 /* get context ref */
342 [ FILTER_OP_GET_CONTEXT_REF
] = &&LABEL_FILTER_OP_GET_CONTEXT_REF
,
343 [ FILTER_OP_GET_CONTEXT_REF_STRING
] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_STRING
,
344 [ FILTER_OP_GET_CONTEXT_REF_S64
] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_S64
,
345 [ FILTER_OP_GET_CONTEXT_REF_DOUBLE
] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_DOUBLE
,
347 #endif /* #ifndef INTERPRETER_USE_SWITCH */
351 OP(FILTER_OP_UNKNOWN
):
352 OP(FILTER_OP_LOAD_FIELD_REF
):
353 #ifdef INTERPRETER_USE_SWITCH
355 #endif /* INTERPRETER_USE_SWITCH */
356 ERR("unknown bytecode op %u\n",
357 (unsigned int) *(filter_opcode_t
*) pc
);
361 OP(FILTER_OP_RETURN
):
362 /* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */
363 retval
= !!estack_ax_v
;
373 OP(FILTER_OP_RSHIFT
):
374 OP(FILTER_OP_LSHIFT
):
375 OP(FILTER_OP_BIN_AND
):
376 OP(FILTER_OP_BIN_OR
):
377 OP(FILTER_OP_BIN_XOR
):
378 ERR("unsupported bytecode op %u\n",
379 (unsigned int) *(filter_opcode_t
*) pc
);
385 /* Dynamic typing. */
386 switch (estack_ax_t
) {
388 switch (estack_bx_t
) {
390 JUMP_TO(FILTER_OP_EQ_S64
);
392 JUMP_TO(FILTER_OP_EQ_DOUBLE_S64
);
393 case REG_STRING
: /* Fall-through */
394 case REG_STAR_GLOB_STRING
:
398 ERR("Unknown filter register type (%d)",
405 switch (estack_bx_t
) {
407 JUMP_TO(FILTER_OP_EQ_S64_DOUBLE
);
409 JUMP_TO(FILTER_OP_EQ_DOUBLE
);
410 case REG_STRING
: /* Fall-through */
411 case REG_STAR_GLOB_STRING
:
415 ERR("Unknown filter register type (%d)",
422 switch (estack_bx_t
) {
423 case REG_S64
: /* Fall-through */
428 JUMP_TO(FILTER_OP_EQ_STRING
);
429 case REG_STAR_GLOB_STRING
:
430 JUMP_TO(FILTER_OP_EQ_STAR_GLOB_STRING
);
432 ERR("Unknown filter register type (%d)",
438 case REG_STAR_GLOB_STRING
:
439 switch (estack_bx_t
) {
440 case REG_S64
: /* Fall-through */
445 JUMP_TO(FILTER_OP_EQ_STAR_GLOB_STRING
);
446 case REG_STAR_GLOB_STRING
:
450 ERR("Unknown filter register type (%d)",
457 ERR("Unknown filter register type (%d)",
465 /* Dynamic typing. */
466 switch (estack_ax_t
) {
468 switch (estack_bx_t
) {
470 JUMP_TO(FILTER_OP_NE_S64
);
472 JUMP_TO(FILTER_OP_NE_DOUBLE_S64
);
473 case REG_STRING
: /* Fall-through */
474 case REG_STAR_GLOB_STRING
:
478 ERR("Unknown filter register type (%d)",
485 switch (estack_bx_t
) {
487 JUMP_TO(FILTER_OP_NE_S64_DOUBLE
);
489 JUMP_TO(FILTER_OP_NE_DOUBLE
);
490 case REG_STRING
: /* Fall-through */
491 case REG_STAR_GLOB_STRING
:
495 ERR("Unknown filter register type (%d)",
502 switch (estack_bx_t
) {
503 case REG_S64
: /* Fall-through */
508 JUMP_TO(FILTER_OP_NE_STRING
);
509 case REG_STAR_GLOB_STRING
:
510 JUMP_TO(FILTER_OP_NE_STAR_GLOB_STRING
);
512 ERR("Unknown filter register type (%d)",
518 case REG_STAR_GLOB_STRING
:
519 switch (estack_bx_t
) {
520 case REG_S64
: /* Fall-through */
525 JUMP_TO(FILTER_OP_NE_STAR_GLOB_STRING
);
526 case REG_STAR_GLOB_STRING
:
530 ERR("Unknown filter register type (%d)",
537 ERR("Unknown filter register type (%d)",
545 /* Dynamic typing. */
546 switch (estack_ax_t
) {
548 switch (estack_bx_t
) {
550 JUMP_TO(FILTER_OP_GT_S64
);
552 JUMP_TO(FILTER_OP_GT_DOUBLE_S64
);
553 case REG_STRING
: /* Fall-through */
554 case REG_STAR_GLOB_STRING
:
558 ERR("Unknown filter register type (%d)",
565 switch (estack_bx_t
) {
567 JUMP_TO(FILTER_OP_GT_S64_DOUBLE
);
569 JUMP_TO(FILTER_OP_GT_DOUBLE
);
570 case REG_STRING
: /* Fall-through */
571 case REG_STAR_GLOB_STRING
:
575 ERR("Unknown filter register type (%d)",
582 switch (estack_bx_t
) {
583 case REG_S64
: /* Fall-through */
584 case REG_DOUBLE
: /* Fall-through */
585 case REG_STAR_GLOB_STRING
:
589 JUMP_TO(FILTER_OP_GT_STRING
);
591 ERR("Unknown filter register type (%d)",
598 ERR("Unknown filter register type (%d)",
606 /* Dynamic typing. */
607 switch (estack_ax_t
) {
609 switch (estack_bx_t
) {
611 JUMP_TO(FILTER_OP_LT_S64
);
613 JUMP_TO(FILTER_OP_LT_DOUBLE_S64
);
614 case REG_STRING
: /* Fall-through */
615 case REG_STAR_GLOB_STRING
:
619 ERR("Unknown filter register type (%d)",
626 switch (estack_bx_t
) {
628 JUMP_TO(FILTER_OP_LT_S64_DOUBLE
);
630 JUMP_TO(FILTER_OP_LT_DOUBLE
);
631 case REG_STRING
: /* Fall-through */
632 case REG_STAR_GLOB_STRING
:
636 ERR("Unknown filter register type (%d)",
643 switch (estack_bx_t
) {
644 case REG_S64
: /* Fall-through */
645 case REG_DOUBLE
: /* Fall-through */
646 case REG_STAR_GLOB_STRING
:
650 JUMP_TO(FILTER_OP_LT_STRING
);
652 ERR("Unknown filter register type (%d)",
659 ERR("Unknown filter register type (%d)",
667 /* Dynamic typing. */
668 switch (estack_ax_t
) {
670 switch (estack_bx_t
) {
672 JUMP_TO(FILTER_OP_GE_S64
);
674 JUMP_TO(FILTER_OP_GE_DOUBLE_S64
);
675 case REG_STRING
: /* Fall-through */
676 case REG_STAR_GLOB_STRING
:
680 ERR("Unknown filter register type (%d)",
687 switch (estack_bx_t
) {
689 JUMP_TO(FILTER_OP_GE_S64_DOUBLE
);
691 JUMP_TO(FILTER_OP_GE_DOUBLE
);
692 case REG_STRING
: /* Fall-through */
693 case REG_STAR_GLOB_STRING
:
697 ERR("Unknown filter register type (%d)",
704 switch (estack_bx_t
) {
705 case REG_S64
: /* Fall-through */
706 case REG_DOUBLE
: /* Fall-through */
707 case REG_STAR_GLOB_STRING
:
711 JUMP_TO(FILTER_OP_GE_STRING
);
713 ERR("Unknown filter register type (%d)",
720 ERR("Unknown filter register type (%d)",
728 /* Dynamic typing. */
729 switch (estack_ax_t
) {
731 switch (estack_bx_t
) {
733 JUMP_TO(FILTER_OP_LE_S64
);
735 JUMP_TO(FILTER_OP_LE_DOUBLE_S64
);
736 case REG_STRING
: /* Fall-through */
737 case REG_STAR_GLOB_STRING
:
741 ERR("Unknown filter register type (%d)",
748 switch (estack_bx_t
) {
750 JUMP_TO(FILTER_OP_LE_S64_DOUBLE
);
752 JUMP_TO(FILTER_OP_LE_DOUBLE
);
753 case REG_STRING
: /* Fall-through */
754 case REG_STAR_GLOB_STRING
:
758 ERR("Unknown filter register type (%d)",
765 switch (estack_bx_t
) {
766 case REG_S64
: /* Fall-through */
767 case REG_DOUBLE
: /* Fall-through */
768 case REG_STAR_GLOB_STRING
:
772 JUMP_TO(FILTER_OP_LE_STRING
);
774 ERR("Unknown filter register type (%d)",
781 ERR("Unknown filter register type (%d)",
788 OP(FILTER_OP_EQ_STRING
):
792 res
= (stack_strcmp(stack
, top
, "==") == 0);
793 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
795 estack_ax_t
= REG_S64
;
796 next_pc
+= sizeof(struct binary_op
);
799 OP(FILTER_OP_NE_STRING
):
803 res
= (stack_strcmp(stack
, top
, "!=") != 0);
804 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
806 estack_ax_t
= REG_S64
;
807 next_pc
+= sizeof(struct binary_op
);
810 OP(FILTER_OP_GT_STRING
):
814 res
= (stack_strcmp(stack
, top
, ">") > 0);
815 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
817 estack_ax_t
= REG_S64
;
818 next_pc
+= sizeof(struct binary_op
);
821 OP(FILTER_OP_LT_STRING
):
825 res
= (stack_strcmp(stack
, top
, "<") < 0);
826 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
828 estack_ax_t
= REG_S64
;
829 next_pc
+= sizeof(struct binary_op
);
832 OP(FILTER_OP_GE_STRING
):
836 res
= (stack_strcmp(stack
, top
, ">=") >= 0);
837 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
839 estack_ax_t
= REG_S64
;
840 next_pc
+= sizeof(struct binary_op
);
843 OP(FILTER_OP_LE_STRING
):
847 res
= (stack_strcmp(stack
, top
, "<=") <= 0);
848 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
850 estack_ax_t
= REG_S64
;
851 next_pc
+= sizeof(struct binary_op
);
855 OP(FILTER_OP_EQ_STAR_GLOB_STRING
):
859 res
= (stack_star_glob_match(stack
, top
, "==") == 0);
860 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
862 estack_ax_t
= REG_S64
;
863 next_pc
+= sizeof(struct binary_op
);
866 OP(FILTER_OP_NE_STAR_GLOB_STRING
):
870 res
= (stack_star_glob_match(stack
, top
, "!=") != 0);
871 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
873 estack_ax_t
= REG_S64
;
874 next_pc
+= sizeof(struct binary_op
);
878 OP(FILTER_OP_EQ_S64
):
882 res
= (estack_bx_v
== estack_ax_v
);
883 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
885 estack_ax_t
= REG_S64
;
886 next_pc
+= sizeof(struct binary_op
);
889 OP(FILTER_OP_NE_S64
):
893 res
= (estack_bx_v
!= estack_ax_v
);
894 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
896 estack_ax_t
= REG_S64
;
897 next_pc
+= sizeof(struct binary_op
);
900 OP(FILTER_OP_GT_S64
):
904 res
= (estack_bx_v
> estack_ax_v
);
905 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
907 estack_ax_t
= REG_S64
;
908 next_pc
+= sizeof(struct binary_op
);
911 OP(FILTER_OP_LT_S64
):
915 res
= (estack_bx_v
< estack_ax_v
);
916 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
918 estack_ax_t
= REG_S64
;
919 next_pc
+= sizeof(struct binary_op
);
922 OP(FILTER_OP_GE_S64
):
926 res
= (estack_bx_v
>= estack_ax_v
);
927 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
929 estack_ax_t
= REG_S64
;
930 next_pc
+= sizeof(struct binary_op
);
933 OP(FILTER_OP_LE_S64
):
937 res
= (estack_bx_v
<= estack_ax_v
);
938 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
940 estack_ax_t
= REG_S64
;
941 next_pc
+= sizeof(struct binary_op
);
945 OP(FILTER_OP_EQ_DOUBLE
):
949 res
= (estack_bx(stack
, top
)->u
.d
== estack_ax(stack
, top
)->u
.d
);
950 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
952 estack_ax_t
= REG_S64
;
953 next_pc
+= sizeof(struct binary_op
);
956 OP(FILTER_OP_NE_DOUBLE
):
960 res
= (estack_bx(stack
, top
)->u
.d
!= estack_ax(stack
, top
)->u
.d
);
961 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
963 estack_ax_t
= REG_S64
;
964 next_pc
+= sizeof(struct binary_op
);
967 OP(FILTER_OP_GT_DOUBLE
):
971 res
= (estack_bx(stack
, top
)->u
.d
> estack_ax(stack
, top
)->u
.d
);
972 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
974 estack_ax_t
= REG_S64
;
975 next_pc
+= sizeof(struct binary_op
);
978 OP(FILTER_OP_LT_DOUBLE
):
982 res
= (estack_bx(stack
, top
)->u
.d
< estack_ax(stack
, top
)->u
.d
);
983 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
985 estack_ax_t
= REG_S64
;
986 next_pc
+= sizeof(struct binary_op
);
989 OP(FILTER_OP_GE_DOUBLE
):
993 res
= (estack_bx(stack
, top
)->u
.d
>= estack_ax(stack
, top
)->u
.d
);
994 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
996 estack_ax_t
= REG_S64
;
997 next_pc
+= sizeof(struct binary_op
);
1000 OP(FILTER_OP_LE_DOUBLE
):
1004 res
= (estack_bx(stack
, top
)->u
.d
<= estack_ax(stack
, top
)->u
.d
);
1005 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1007 estack_ax_t
= REG_S64
;
1008 next_pc
+= sizeof(struct binary_op
);
1012 /* Mixed S64-double binary comparators */
1013 OP(FILTER_OP_EQ_DOUBLE_S64
):
1017 res
= (estack_bx(stack
, top
)->u
.d
== estack_ax_v
);
1018 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1020 estack_ax_t
= REG_S64
;
1021 next_pc
+= sizeof(struct binary_op
);
1024 OP(FILTER_OP_NE_DOUBLE_S64
):
1028 res
= (estack_bx(stack
, top
)->u
.d
!= estack_ax_v
);
1029 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1031 estack_ax_t
= REG_S64
;
1032 next_pc
+= sizeof(struct binary_op
);
1035 OP(FILTER_OP_GT_DOUBLE_S64
):
1039 res
= (estack_bx(stack
, top
)->u
.d
> estack_ax_v
);
1040 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1042 estack_ax_t
= REG_S64
;
1043 next_pc
+= sizeof(struct binary_op
);
1046 OP(FILTER_OP_LT_DOUBLE_S64
):
1050 res
= (estack_bx(stack
, top
)->u
.d
< estack_ax_v
);
1051 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1053 estack_ax_t
= REG_S64
;
1054 next_pc
+= sizeof(struct binary_op
);
1057 OP(FILTER_OP_GE_DOUBLE_S64
):
1061 res
= (estack_bx(stack
, top
)->u
.d
>= estack_ax_v
);
1062 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1064 estack_ax_t
= REG_S64
;
1065 next_pc
+= sizeof(struct binary_op
);
1068 OP(FILTER_OP_LE_DOUBLE_S64
):
1072 res
= (estack_bx(stack
, top
)->u
.d
<= estack_ax_v
);
1073 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1075 estack_ax_t
= REG_S64
;
1076 next_pc
+= sizeof(struct binary_op
);
1080 OP(FILTER_OP_EQ_S64_DOUBLE
):
1084 res
= (estack_bx_v
== estack_ax(stack
, top
)->u
.d
);
1085 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1087 estack_ax_t
= REG_S64
;
1088 next_pc
+= sizeof(struct binary_op
);
1091 OP(FILTER_OP_NE_S64_DOUBLE
):
1095 res
= (estack_bx_v
!= estack_ax(stack
, top
)->u
.d
);
1096 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1098 estack_ax_t
= REG_S64
;
1099 next_pc
+= sizeof(struct binary_op
);
1102 OP(FILTER_OP_GT_S64_DOUBLE
):
1106 res
= (estack_bx_v
> estack_ax(stack
, top
)->u
.d
);
1107 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1109 estack_ax_t
= REG_S64
;
1110 next_pc
+= sizeof(struct binary_op
);
1113 OP(FILTER_OP_LT_S64_DOUBLE
):
1117 res
= (estack_bx_v
< estack_ax(stack
, top
)->u
.d
);
1118 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1120 estack_ax_t
= REG_S64
;
1121 next_pc
+= sizeof(struct binary_op
);
1124 OP(FILTER_OP_GE_S64_DOUBLE
):
1128 res
= (estack_bx_v
>= estack_ax(stack
, top
)->u
.d
);
1129 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1131 estack_ax_t
= REG_S64
;
1132 next_pc
+= sizeof(struct binary_op
);
1135 OP(FILTER_OP_LE_S64_DOUBLE
):
1139 res
= (estack_bx_v
<= estack_ax(stack
, top
)->u
.d
);
1140 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1142 estack_ax_t
= REG_S64
;
1143 next_pc
+= sizeof(struct binary_op
);
1148 OP(FILTER_OP_UNARY_PLUS
):
1150 /* Dynamic typing. */
1151 switch (estack_ax_t
) {
1152 case REG_S64
: /* Fall-through. */
1153 JUMP_TO(FILTER_OP_UNARY_PLUS_S64
);
1155 JUMP_TO(FILTER_OP_UNARY_PLUS_DOUBLE
);
1156 case REG_STRING
: /* Fall-through */
1157 case REG_STAR_GLOB_STRING
:
1161 ERR("Unknown filter register type (%d)",
1167 OP(FILTER_OP_UNARY_MINUS
):
1169 /* Dynamic typing. */
1170 switch (estack_ax_t
) {
1172 JUMP_TO(FILTER_OP_UNARY_MINUS_S64
);
1174 JUMP_TO(FILTER_OP_UNARY_MINUS_DOUBLE
);
1175 case REG_STRING
: /* Fall-through */
1176 case REG_STAR_GLOB_STRING
:
1180 ERR("Unknown filter register type (%d)",
1186 OP(FILTER_OP_UNARY_NOT
):
1188 /* Dynamic typing. */
1189 switch (estack_ax_t
) {
1191 JUMP_TO(FILTER_OP_UNARY_NOT_S64
);
1193 JUMP_TO(FILTER_OP_UNARY_NOT_DOUBLE
);
1194 case REG_STRING
: /* Fall-through */
1195 case REG_STAR_GLOB_STRING
:
1199 ERR("Unknown filter register type (%d)",
1204 next_pc
+= sizeof(struct unary_op
);
1208 OP(FILTER_OP_UNARY_PLUS_S64
):
1209 OP(FILTER_OP_UNARY_PLUS_DOUBLE
):
1211 next_pc
+= sizeof(struct unary_op
);
1214 OP(FILTER_OP_UNARY_MINUS_S64
):
1216 estack_ax_v
= -estack_ax_v
;
1217 next_pc
+= sizeof(struct unary_op
);
1220 OP(FILTER_OP_UNARY_MINUS_DOUBLE
):
1222 estack_ax(stack
, top
)->u
.d
= -estack_ax(stack
, top
)->u
.d
;
1223 next_pc
+= sizeof(struct unary_op
);
1226 OP(FILTER_OP_UNARY_NOT_S64
):
1228 estack_ax_v
= !estack_ax_v
;
1229 next_pc
+= sizeof(struct unary_op
);
1232 OP(FILTER_OP_UNARY_NOT_DOUBLE
):
1234 estack_ax_v
= !estack_ax(stack
, top
)->u
.d
;
1235 estack_ax_t
= REG_S64
;
1236 next_pc
+= sizeof(struct unary_op
);
1243 struct logical_op
*insn
= (struct logical_op
*) pc
;
1245 if (estack_ax_t
!= REG_S64
) {
1249 /* If AX is 0, skip and evaluate to 0 */
1250 if (unlikely(estack_ax_v
== 0)) {
1251 dbg_printf("Jumping to bytecode offset %u\n",
1252 (unsigned int) insn
->skip_offset
);
1253 next_pc
= start_pc
+ insn
->skip_offset
;
1255 /* Pop 1 when jump not taken */
1256 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1257 next_pc
+= sizeof(struct logical_op
);
1263 struct logical_op
*insn
= (struct logical_op
*) pc
;
1265 if (estack_ax_t
!= REG_S64
) {
1269 /* If AX is nonzero, skip and evaluate to 1 */
1270 if (unlikely(estack_ax_v
!= 0)) {
1272 dbg_printf("Jumping to bytecode offset %u\n",
1273 (unsigned int) insn
->skip_offset
);
1274 next_pc
= start_pc
+ insn
->skip_offset
;
1276 /* Pop 1 when jump not taken */
1277 estack_pop(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1278 next_pc
+= sizeof(struct logical_op
);
1284 /* load field ref */
1285 OP(FILTER_OP_LOAD_FIELD_REF_STRING
):
1287 struct load_op
*insn
= (struct load_op
*) pc
;
1288 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1290 dbg_printf("load field ref offset %u type string\n",
1292 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1293 estack_ax(stack
, top
)->u
.s
.str
=
1294 *(const char * const *) &filter_stack_data
[ref
->offset
];
1295 if (unlikely(!estack_ax(stack
, top
)->u
.s
.str
)) {
1296 dbg_printf("Filter warning: loading a NULL string.\n");
1300 estack_ax(stack
, top
)->u
.s
.seq_len
= SIZE_MAX
;
1301 estack_ax(stack
, top
)->u
.s
.literal_type
=
1302 ESTACK_STRING_LITERAL_TYPE_NONE
;
1303 estack_ax_t
= REG_STRING
;
1304 dbg_printf("ref load string %s\n", estack_ax(stack
, top
)->u
.s
.str
);
1305 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1309 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE
):
1311 struct load_op
*insn
= (struct load_op
*) pc
;
1312 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1314 dbg_printf("load field ref offset %u type sequence\n",
1316 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1317 estack_ax(stack
, top
)->u
.s
.seq_len
=
1318 *(unsigned long *) &filter_stack_data
[ref
->offset
];
1319 estack_ax(stack
, top
)->u
.s
.str
=
1320 *(const char **) (&filter_stack_data
[ref
->offset
1321 + sizeof(unsigned long)]);
1322 estack_ax_t
= REG_STRING
;
1323 if (unlikely(!estack_ax(stack
, top
)->u
.s
.str
)) {
1324 dbg_printf("Filter warning: loading a NULL sequence.\n");
1328 estack_ax(stack
, top
)->u
.s
.literal_type
=
1329 ESTACK_STRING_LITERAL_TYPE_NONE
;
1330 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1334 OP(FILTER_OP_LOAD_FIELD_REF_S64
):
1336 struct load_op
*insn
= (struct load_op
*) pc
;
1337 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1339 dbg_printf("load field ref offset %u type s64\n",
1341 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1343 ((struct literal_numeric
*) &filter_stack_data
[ref
->offset
])->v
;
1344 estack_ax_t
= REG_S64
;
1345 dbg_printf("ref load s64 %" PRIi64
"\n", estack_ax_v
);
1346 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1350 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE
):
1352 struct load_op
*insn
= (struct load_op
*) pc
;
1353 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1355 dbg_printf("load field ref offset %u type double\n",
1357 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1358 memcpy(&estack_ax(stack
, top
)->u
.d
, &filter_stack_data
[ref
->offset
],
1359 sizeof(struct literal_double
));
1360 estack_ax_t
= REG_DOUBLE
;
1361 dbg_printf("ref load double %g\n", estack_ax(stack
, top
)->u
.d
);
1362 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1366 /* load from immediate operand */
1367 OP(FILTER_OP_LOAD_STRING
):
1369 struct load_op
*insn
= (struct load_op
*) pc
;
1371 dbg_printf("load string %s\n", insn
->data
);
1372 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1373 estack_ax(stack
, top
)->u
.s
.str
= insn
->data
;
1374 estack_ax(stack
, top
)->u
.s
.seq_len
= SIZE_MAX
;
1375 estack_ax(stack
, top
)->u
.s
.literal_type
=
1376 ESTACK_STRING_LITERAL_TYPE_PLAIN
;
1377 estack_ax_t
= REG_STRING
;
1378 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1382 OP(FILTER_OP_LOAD_STAR_GLOB_STRING
):
1384 struct load_op
*insn
= (struct load_op
*) pc
;
1386 dbg_printf("load globbing pattern %s\n", insn
->data
);
1387 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1388 estack_ax(stack
, top
)->u
.s
.str
= insn
->data
;
1389 estack_ax(stack
, top
)->u
.s
.seq_len
= SIZE_MAX
;
1390 estack_ax(stack
, top
)->u
.s
.literal_type
=
1391 ESTACK_STRING_LITERAL_TYPE_STAR_GLOB
;
1392 estack_ax_t
= REG_STAR_GLOB_STRING
;
1393 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1397 OP(FILTER_OP_LOAD_S64
):
1399 struct load_op
*insn
= (struct load_op
*) pc
;
1401 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1402 estack_ax_v
= ((struct literal_numeric
*) insn
->data
)->v
;
1403 estack_ax_t
= REG_S64
;
1404 dbg_printf("load s64 %" PRIi64
"\n", estack_ax_v
);
1405 next_pc
+= sizeof(struct load_op
)
1406 + sizeof(struct literal_numeric
);
1410 OP(FILTER_OP_LOAD_DOUBLE
):
1412 struct load_op
*insn
= (struct load_op
*) pc
;
1414 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1415 memcpy(&estack_ax(stack
, top
)->u
.d
, insn
->data
,
1416 sizeof(struct literal_double
));
1417 estack_ax_t
= REG_DOUBLE
;
1418 dbg_printf("load double %g\n", estack_ax(stack
, top
)->u
.d
);
1419 next_pc
+= sizeof(struct load_op
)
1420 + sizeof(struct literal_double
);
1425 OP(FILTER_OP_CAST_TO_S64
):
1427 /* Dynamic typing. */
1428 switch (estack_ax_t
) {
1430 JUMP_TO(FILTER_OP_CAST_NOP
);
1432 JUMP_TO(FILTER_OP_CAST_DOUBLE_TO_S64
);
1433 case REG_STRING
: /* Fall-through */
1434 case REG_STAR_GLOB_STRING
:
1438 ERR("Unknown filter register type (%d)",
1445 OP(FILTER_OP_CAST_DOUBLE_TO_S64
):
1447 estack_ax_v
= (int64_t) estack_ax(stack
, top
)->u
.d
;
1448 estack_ax_t
= REG_S64
;
1449 next_pc
+= sizeof(struct cast_op
);
1453 OP(FILTER_OP_CAST_NOP
):
1455 next_pc
+= sizeof(struct cast_op
);
1459 /* get context ref */
1460 OP(FILTER_OP_GET_CONTEXT_REF
):
1462 struct load_op
*insn
= (struct load_op
*) pc
;
1463 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1464 struct lttng_ctx
*ctx
;
1465 struct lttng_ctx_field
*ctx_field
;
1466 struct lttng_ctx_value v
;
1468 dbg_printf("get context ref offset %u type dynamic\n",
1470 ctx
= rcu_dereference(session
->ctx
);
1471 ctx_field
= &ctx
->fields
[ref
->offset
];
1472 ctx_field
->get_value(ctx_field
, &v
);
1473 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1475 case LTTNG_UST_DYNAMIC_TYPE_NONE
:
1478 case LTTNG_UST_DYNAMIC_TYPE_S64
:
1479 estack_ax_v
= v
.u
.s64
;
1480 estack_ax_t
= REG_S64
;
1481 dbg_printf("ref get context dynamic s64 %" PRIi64
"\n", estack_ax_v
);
1483 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE
:
1484 estack_ax(stack
, top
)->u
.d
= v
.u
.d
;
1485 estack_ax_t
= REG_DOUBLE
;
1486 dbg_printf("ref get context dynamic double %g\n", estack_ax(stack
, top
)->u
.d
);
1488 case LTTNG_UST_DYNAMIC_TYPE_STRING
:
1489 estack_ax(stack
, top
)->u
.s
.str
= v
.u
.str
;
1490 if (unlikely(!estack_ax(stack
, top
)->u
.s
.str
)) {
1491 dbg_printf("Filter warning: loading a NULL string.\n");
1495 estack_ax(stack
, top
)->u
.s
.seq_len
= SIZE_MAX
;
1496 estack_ax(stack
, top
)->u
.s
.literal_type
=
1497 ESTACK_STRING_LITERAL_TYPE_NONE
;
1498 dbg_printf("ref get context dynamic string %s\n", estack_ax(stack
, top
)->u
.s
.str
);
1499 estack_ax_t
= REG_STRING
;
1502 dbg_printf("Filter warning: unknown dynamic type (%d).\n", (int) v
.sel
);
1506 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1510 OP(FILTER_OP_GET_CONTEXT_REF_STRING
):
1512 struct load_op
*insn
= (struct load_op
*) pc
;
1513 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1514 struct lttng_ctx
*ctx
;
1515 struct lttng_ctx_field
*ctx_field
;
1516 struct lttng_ctx_value v
;
1518 dbg_printf("get context ref offset %u type string\n",
1520 ctx
= rcu_dereference(session
->ctx
);
1521 ctx_field
= &ctx
->fields
[ref
->offset
];
1522 ctx_field
->get_value(ctx_field
, &v
);
1523 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1524 estack_ax(stack
, top
)->u
.s
.str
= v
.u
.str
;
1525 if (unlikely(!estack_ax(stack
, top
)->u
.s
.str
)) {
1526 dbg_printf("Filter warning: loading a NULL string.\n");
1530 estack_ax(stack
, top
)->u
.s
.seq_len
= SIZE_MAX
;
1531 estack_ax(stack
, top
)->u
.s
.literal_type
=
1532 ESTACK_STRING_LITERAL_TYPE_NONE
;
1533 estack_ax_t
= REG_STRING
;
1534 dbg_printf("ref get context string %s\n", estack_ax(stack
, top
)->u
.s
.str
);
1535 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1539 OP(FILTER_OP_GET_CONTEXT_REF_S64
):
1541 struct load_op
*insn
= (struct load_op
*) pc
;
1542 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1543 struct lttng_ctx
*ctx
;
1544 struct lttng_ctx_field
*ctx_field
;
1545 struct lttng_ctx_value v
;
1547 dbg_printf("get context ref offset %u type s64\n",
1549 ctx
= rcu_dereference(session
->ctx
);
1550 ctx_field
= &ctx
->fields
[ref
->offset
];
1551 ctx_field
->get_value(ctx_field
, &v
);
1552 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1553 estack_ax_v
= v
.u
.s64
;
1554 estack_ax_t
= REG_S64
;
1555 dbg_printf("ref get context s64 %" PRIi64
"\n", estack_ax_v
);
1556 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1560 OP(FILTER_OP_GET_CONTEXT_REF_DOUBLE
):
1562 struct load_op
*insn
= (struct load_op
*) pc
;
1563 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1564 struct lttng_ctx
*ctx
;
1565 struct lttng_ctx_field
*ctx_field
;
1566 struct lttng_ctx_value v
;
1568 dbg_printf("get context ref offset %u type double\n",
1570 ctx
= rcu_dereference(session
->ctx
);
1571 ctx_field
= &ctx
->fields
[ref
->offset
];
1572 ctx_field
->get_value(ctx_field
, &v
);
1573 estack_push(stack
, top
, ax
, bx
, ax_t
, bx_t
);
1574 memcpy(&estack_ax(stack
, top
)->u
.d
, &v
.u
.d
, sizeof(struct literal_double
));
1575 estack_ax_t
= REG_DOUBLE
;
1576 dbg_printf("ref get context double %g\n", estack_ax(stack
, top
)->u
.d
);
1577 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1583 /* return 0 (discard) on error */