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",
107 [ FILTER_OP_EQ
] = "EQ",
108 [ FILTER_OP_NE
] = "NE",
109 [ FILTER_OP_GT
] = "GT",
110 [ FILTER_OP_LT
] = "LT",
111 [ FILTER_OP_GE
] = "GE",
112 [ FILTER_OP_LE
] = "LE",
115 [ FILTER_OP_UNARY_PLUS
] = "UNARY_PLUS",
116 [ FILTER_OP_UNARY_MINUS
] = "UNARY_MINUS",
117 [ FILTER_OP_UNARY_NOT
] = "UNARY_NOT",
120 [ FILTER_OP_AND
] = "AND",
121 [ FILTER_OP_OR
] = "OR",
124 [ FILTER_OP_LOAD_FIELD_REF
] = "LOAD_FIELD_REF",
125 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = "LOAD_FIELD_REF_STRING",
126 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = "LOAD_FIELD_REF_SEQUENCE",
127 [ FILTER_OP_LOAD_FIELD_REF_S64
] = "LOAD_FIELD_REF_S64",
128 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = "LOAD_FIELD_REF_DOUBLE",
130 [ FILTER_OP_LOAD_STRING
] = "LOAD_STRING",
131 [ FILTER_OP_LOAD_S64
] = "LOAD_S64",
132 [ FILTER_OP_LOAD_DOUBLE
] = "LOAD_DOUBLE",
136 const char *print_op(enum filter_op op
)
138 if (op
>= NR_FILTER_OPS
)
145 * -1: wildcard found.
146 * -2: unknown escape char.
151 int parse_char(const char **p
)
171 int reg_strcmp(struct reg reg
[NR_REG
], const char *cmp_type
)
173 const char *p
= reg
[REG_R0
].str
, *q
= reg
[REG_R1
].str
;
180 if (unlikely(p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')) {
181 if (q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')
187 if (unlikely(q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')) {
188 if (p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')
194 if (reg
[REG_R0
].literal
) {
195 ret
= parse_char(&p
);
198 } else if (ret
== -2) {
201 /* else compare both char */
203 if (reg
[REG_R1
].literal
) {
204 ret
= parse_char(&q
);
207 } else if (ret
== -2) {
228 int lttng_filter_false(void *filter_data
,
229 const char *filter_stack_data
)
235 int lttng_filter_interpret_bytecode(void *filter_data
,
236 const char *filter_stack_data
)
238 struct bytecode_runtime
*bytecode
= filter_data
;
239 void *pc
, *next_pc
, *start_pc
;
242 struct reg reg
[NR_REG
];
244 start_pc
= &bytecode
->data
[0];
245 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
247 dbg_printf("Executing op %s (%u)\n",
248 print_op((unsigned int) *(filter_opcode_t
*) pc
),
249 (unsigned int) *(filter_opcode_t
*) pc
);
250 switch (*(filter_opcode_t
*) pc
) {
251 case FILTER_OP_UNKNOWN
:
252 case FILTER_OP_LOAD_FIELD_REF
:
254 ERR("unknown bytecode op %u\n",
255 (unsigned int) *(filter_opcode_t
*) pc
);
259 case FILTER_OP_RETURN
:
269 case FILTER_OP_MINUS
:
270 case FILTER_OP_RSHIFT
:
271 case FILTER_OP_LSHIFT
:
272 case FILTER_OP_BIN_AND
:
273 case FILTER_OP_BIN_OR
:
274 case FILTER_OP_BIN_XOR
:
275 ERR("unsupported bytecode op %u\n",
276 (unsigned int) *(filter_opcode_t
*) pc
);
282 switch (reg
[REG_R0
].type
) {
284 ERR("unknown register type\n");
289 reg
[REG_R0
].v
= (reg_strcmp(reg
, "==") == 0);
292 switch (reg
[REG_R1
].type
) {
294 ERR("unknown register type\n");
299 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].v
);
302 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].d
);
307 switch (reg
[REG_R1
].type
) {
309 ERR("unknown register type\n");
314 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].v
);
317 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].d
);
322 reg
[REG_R0
].type
= REG_S64
;
323 next_pc
+= sizeof(struct binary_op
);
328 switch (reg
[REG_R0
].type
) {
330 ERR("unknown register type\n");
335 reg
[REG_R0
].v
= (reg_strcmp(reg
, "!=") != 0);
338 switch (reg
[REG_R1
].type
) {
340 ERR("unknown register type\n");
345 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].v
);
348 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].d
);
353 switch (reg
[REG_R1
].type
) {
355 ERR("unknown register type\n");
360 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].v
);
363 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].d
);
368 reg
[REG_R0
].type
= REG_S64
;
369 next_pc
+= sizeof(struct binary_op
);
374 switch (reg
[REG_R0
].type
) {
376 ERR("unknown register type\n");
381 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">") > 0);
384 switch (reg
[REG_R1
].type
) {
386 ERR("unknown register type\n");
391 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].v
);
394 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].d
);
399 switch (reg
[REG_R1
].type
) {
401 ERR("unknown register type\n");
406 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].v
);
409 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].d
);
414 reg
[REG_R0
].type
= REG_S64
;
415 next_pc
+= sizeof(struct binary_op
);
420 switch (reg
[REG_R0
].type
) {
422 ERR("unknown register type\n");
427 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<") < 0);
430 switch (reg
[REG_R1
].type
) {
432 ERR("unknown register type\n");
437 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].v
);
440 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].d
);
445 switch (reg
[REG_R1
].type
) {
447 ERR("unknown register type\n");
452 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].v
);
455 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].d
);
460 reg
[REG_R0
].type
= REG_S64
;
461 next_pc
+= sizeof(struct binary_op
);
466 switch (reg
[REG_R0
].type
) {
468 ERR("unknown register type\n");
473 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">=") >= 0);
476 switch (reg
[REG_R1
].type
) {
478 ERR("unknown register type\n");
483 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].v
);
486 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].d
);
491 switch (reg
[REG_R1
].type
) {
493 ERR("unknown register type\n");
498 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].v
);
501 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].d
);
506 reg
[REG_R0
].type
= REG_S64
;
507 next_pc
+= sizeof(struct binary_op
);
512 switch (reg
[REG_R0
].type
) {
514 ERR("unknown register type\n");
519 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<=") <= 0);
522 switch (reg
[REG_R1
].type
) {
524 ERR("unknown register type\n");
529 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].v
);
532 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].d
);
537 switch (reg
[REG_R1
].type
) {
539 ERR("unknown register type\n");
544 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].v
);
547 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].d
);
552 reg
[REG_R0
].type
= REG_S64
;
553 next_pc
+= sizeof(struct binary_op
);
558 case FILTER_OP_UNARY_PLUS
:
560 next_pc
+= sizeof(struct unary_op
);
563 case FILTER_OP_UNARY_MINUS
:
565 struct unary_op
*insn
= (struct unary_op
*) pc
;
567 switch (reg
[insn
->reg
].type
) {
569 ERR("unknown register type\n");
574 ERR("Unary minus can only be applied to numeric or floating point registers\n");
578 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
581 reg
[insn
->reg
].d
= -reg
[insn
->reg
].d
;
584 next_pc
+= sizeof(struct unary_op
);
587 case FILTER_OP_UNARY_NOT
:
589 struct unary_op
*insn
= (struct unary_op
*) pc
;
591 switch (reg
[insn
->reg
].type
) {
593 ERR("unknown register type\n");
598 ERR("Unary not can only be applied to numeric or floating point registers\n");
602 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
605 reg
[insn
->reg
].d
= !reg
[insn
->reg
].d
;
608 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
609 next_pc
+= sizeof(struct unary_op
);
615 struct logical_op
*insn
= (struct logical_op
*) pc
;
617 /* If REG_R0 is 0, skip and evaluate to 0 */
618 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
== 0)
619 || (reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
== 0.0)) {
620 dbg_printf("Jumping to bytecode offset %u\n",
621 (unsigned int) insn
->skip_offset
);
622 next_pc
= start_pc
+ insn
->skip_offset
;
624 next_pc
+= sizeof(struct logical_op
);
630 struct logical_op
*insn
= (struct logical_op
*) pc
;
632 /* If REG_R0 is nonzero, skip and evaluate to 1 */
634 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
!= 0)
635 || (reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
!= 0.0)) {
637 dbg_printf("Jumping to bytecode offset %u\n",
638 (unsigned int) insn
->skip_offset
);
639 next_pc
= start_pc
+ insn
->skip_offset
;
641 next_pc
+= sizeof(struct logical_op
);
647 case FILTER_OP_LOAD_FIELD_REF_STRING
:
649 struct load_op
*insn
= (struct load_op
*) pc
;
650 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
652 dbg_printf("load field ref offset %u type string\n",
655 *(const char * const *) &filter_stack_data
[ref
->offset
];
656 reg
[insn
->reg
].type
= REG_STRING
;
657 reg
[insn
->reg
].seq_len
= UINT_MAX
;
658 reg
[insn
->reg
].literal
= 0;
659 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
660 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
664 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
666 struct load_op
*insn
= (struct load_op
*) pc
;
667 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
669 dbg_printf("load field ref offset %u type sequence\n",
671 reg
[insn
->reg
].seq_len
=
672 *(unsigned long *) &filter_stack_data
[ref
->offset
];
674 *(const char **) (&filter_stack_data
[ref
->offset
675 + sizeof(unsigned long)]);
676 reg
[insn
->reg
].type
= REG_STRING
;
677 reg
[insn
->reg
].literal
= 0;
678 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
682 case FILTER_OP_LOAD_FIELD_REF_S64
:
684 struct load_op
*insn
= (struct load_op
*) pc
;
685 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
687 dbg_printf("load field ref offset %u type s64\n",
689 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
690 sizeof(struct literal_numeric
));
691 reg
[insn
->reg
].type
= REG_S64
;
692 reg
[insn
->reg
].literal
= 0;
693 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
694 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
698 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
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 double\n",
705 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
706 sizeof(struct literal_double
));
707 reg
[insn
->reg
].type
= REG_DOUBLE
;
708 reg
[insn
->reg
].literal
= 0;
709 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
710 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
714 case FILTER_OP_LOAD_STRING
:
716 struct load_op
*insn
= (struct load_op
*) pc
;
718 dbg_printf("load string %s\n", insn
->data
);
719 reg
[insn
->reg
].str
= insn
->data
;
720 reg
[insn
->reg
].type
= REG_STRING
;
721 reg
[insn
->reg
].seq_len
= UINT_MAX
;
722 reg
[insn
->reg
].literal
= 1;
723 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
727 case FILTER_OP_LOAD_S64
:
729 struct load_op
*insn
= (struct load_op
*) pc
;
731 memcpy(®
[insn
->reg
].v
, insn
->data
,
732 sizeof(struct literal_numeric
));
733 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
734 reg
[insn
->reg
].type
= REG_S64
;
735 next_pc
+= sizeof(struct load_op
)
736 + sizeof(struct literal_numeric
);
740 case FILTER_OP_LOAD_DOUBLE
:
742 struct load_op
*insn
= (struct load_op
*) pc
;
744 memcpy(®
[insn
->reg
].d
, insn
->data
,
745 sizeof(struct literal_double
));
746 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
747 reg
[insn
->reg
].type
= REG_DOUBLE
;
748 next_pc
+= sizeof(struct load_op
)
749 + sizeof(struct literal_double
);
755 /* return 0 (discard) on error */
762 int bin_op_compare_check(struct vreg reg
[NR_REG
], const char *str
)
764 switch (reg
[REG_R0
].type
) {
769 switch (reg
[REG_R1
].type
) {
782 switch (reg
[REG_R1
].type
) {
801 ERR("type mismatch for '%s' binary operator\n", str
);
806 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
808 void *pc
, *next_pc
, *start_pc
;
810 struct vreg reg
[NR_REG
];
813 for (i
= 0; i
< NR_REG
; i
++) {
814 reg
[i
].type
= REG_TYPE_UNKNOWN
;
818 start_pc
= &bytecode
->data
[0];
819 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
821 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
822 ERR("filter bytecode overflow\n");
826 dbg_printf("Validating op %s (%u)\n",
827 print_op((unsigned int) *(filter_opcode_t
*) pc
),
828 (unsigned int) *(filter_opcode_t
*) pc
);
829 switch (*(filter_opcode_t
*) pc
) {
830 case FILTER_OP_UNKNOWN
:
832 ERR("unknown bytecode op %u\n",
833 (unsigned int) *(filter_opcode_t
*) pc
);
837 case FILTER_OP_RETURN
:
846 case FILTER_OP_MINUS
:
847 case FILTER_OP_RSHIFT
:
848 case FILTER_OP_LSHIFT
:
849 case FILTER_OP_BIN_AND
:
850 case FILTER_OP_BIN_OR
:
851 case FILTER_OP_BIN_XOR
:
852 ERR("unsupported bytecode op %u\n",
853 (unsigned int) *(filter_opcode_t
*) pc
);
859 ret
= bin_op_compare_check(reg
, "==");
862 reg
[REG_R0
].type
= REG_S64
;
863 next_pc
+= sizeof(struct binary_op
);
868 ret
= bin_op_compare_check(reg
, "!=");
871 reg
[REG_R0
].type
= REG_S64
;
872 next_pc
+= sizeof(struct binary_op
);
877 ret
= bin_op_compare_check(reg
, ">");
880 reg
[REG_R0
].type
= REG_S64
;
881 next_pc
+= sizeof(struct binary_op
);
886 ret
= bin_op_compare_check(reg
, "<");
889 reg
[REG_R0
].type
= REG_S64
;
890 next_pc
+= sizeof(struct binary_op
);
895 ret
= bin_op_compare_check(reg
, ">=");
898 reg
[REG_R0
].type
= REG_S64
;
899 next_pc
+= sizeof(struct binary_op
);
904 ret
= bin_op_compare_check(reg
, "<=");
907 reg
[REG_R0
].type
= REG_S64
;
908 next_pc
+= sizeof(struct binary_op
);
913 case FILTER_OP_UNARY_PLUS
:
914 case FILTER_OP_UNARY_MINUS
:
915 case FILTER_OP_UNARY_NOT
:
917 struct unary_op
*insn
= (struct unary_op
*) pc
;
919 if (unlikely(insn
->reg
>= REG_ERROR
)) {
920 ERR("invalid register %u\n",
921 (unsigned int) insn
->reg
);
925 switch (reg
[insn
->reg
].type
) {
927 ERR("unknown register type\n");
932 ERR("Unary op can only be applied to numeric or floating point registers\n");
940 next_pc
+= sizeof(struct unary_op
);
947 struct logical_op
*insn
= (struct logical_op
*) pc
;
949 if (unlikely(reg
[REG_R0
].type
== REG_TYPE_UNKNOWN
950 || reg
[REG_R0
].type
== REG_TYPE_UNKNOWN
951 || reg
[REG_R0
].type
== REG_STRING
952 || reg
[REG_R1
].type
== REG_STRING
)) {
953 ERR("Logical comparator can only be applied to numeric and floating point registers\n");
958 dbg_printf("Validate jumping to bytecode offset %u\n",
959 (unsigned int) insn
->skip_offset
);
960 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
961 ERR("Loops are not allowed in bytecode\n");
965 next_pc
+= sizeof(struct logical_op
);
970 case FILTER_OP_LOAD_FIELD_REF
:
972 ERR("Unknown field ref type\n");
976 case FILTER_OP_LOAD_FIELD_REF_STRING
:
977 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
979 struct load_op
*insn
= (struct load_op
*) pc
;
980 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
982 if (unlikely(insn
->reg
>= REG_ERROR
)) {
983 ERR("invalid register %u\n",
984 (unsigned int) insn
->reg
);
988 dbg_printf("Validate load field ref offset %u type string\n",
990 reg
[insn
->reg
].type
= REG_STRING
;
991 reg
[insn
->reg
].literal
= 0;
992 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
995 case FILTER_OP_LOAD_FIELD_REF_S64
:
997 struct load_op
*insn
= (struct load_op
*) pc
;
998 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1000 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1001 ERR("invalid register %u\n",
1002 (unsigned int) insn
->reg
);
1006 dbg_printf("Validate load field ref offset %u type s64\n",
1008 reg
[insn
->reg
].type
= REG_S64
;
1009 reg
[insn
->reg
].literal
= 0;
1010 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1013 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1015 struct load_op
*insn
= (struct load_op
*) pc
;
1016 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1018 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1019 ERR("invalid register %u\n",
1020 (unsigned int) insn
->reg
);
1024 dbg_printf("Validate load field ref offset %u type double\n",
1026 reg
[insn
->reg
].type
= REG_DOUBLE
;
1027 reg
[insn
->reg
].literal
= 0;
1028 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1032 case FILTER_OP_LOAD_STRING
:
1034 struct load_op
*insn
= (struct load_op
*) pc
;
1036 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1037 ERR("invalid register %u\n",
1038 (unsigned int) insn
->reg
);
1042 reg
[insn
->reg
].type
= REG_STRING
;
1043 reg
[insn
->reg
].literal
= 1;
1044 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1048 case FILTER_OP_LOAD_S64
:
1050 struct load_op
*insn
= (struct load_op
*) pc
;
1052 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1053 ERR("invalid register %u\n",
1054 (unsigned int) insn
->reg
);
1058 reg
[insn
->reg
].type
= REG_S64
;
1059 next_pc
+= sizeof(struct load_op
)
1060 + sizeof(struct literal_numeric
);
1064 case FILTER_OP_LOAD_DOUBLE
:
1066 struct load_op
*insn
= (struct load_op
*) pc
;
1068 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1069 ERR("invalid register %u\n",
1070 (unsigned int) insn
->reg
);
1074 reg
[insn
->reg
].type
= REG_DOUBLE
;
1075 next_pc
+= sizeof(struct load_op
)
1076 + sizeof(struct literal_double
);
1086 int apply_field_reloc(struct ltt_event
*event
,
1087 struct bytecode_runtime
*runtime
,
1088 uint32_t runtime_len
,
1089 uint32_t reloc_offset
,
1090 const char *field_name
)
1092 const struct lttng_event_desc
*desc
;
1093 const struct lttng_event_field
*fields
, *field
= NULL
;
1094 unsigned int nr_fields
, i
;
1095 struct field_ref
*field_ref
;
1097 uint32_t field_offset
= 0;
1099 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1101 /* Ensure that the reloc is within the code */
1102 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1105 /* Lookup event by name */
1109 fields
= desc
->fields
;
1112 nr_fields
= desc
->nr_fields
;
1113 for (i
= 0; i
< nr_fields
; i
++) {
1114 if (!strcmp(fields
[i
].name
, field_name
)) {
1118 /* compute field offset */
1119 switch (fields
[i
].type
.atype
) {
1122 field_offset
+= sizeof(int64_t);
1125 case atype_sequence
:
1126 field_offset
+= sizeof(unsigned long);
1127 field_offset
+= sizeof(void *);
1130 field_offset
+= sizeof(void *);
1133 field_offset
+= sizeof(double);
1142 /* Check if field offset is too large for 16-bit offset */
1143 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1147 op
= (struct load_op
*) &runtime
->data
[reloc_offset
];
1148 field_ref
= (struct field_ref
*) op
->data
;
1149 switch (field
->type
.atype
) {
1152 op
->op
= FILTER_OP_LOAD_FIELD_REF_S64
;
1155 case atype_sequence
:
1156 op
->op
= FILTER_OP_LOAD_FIELD_REF_SEQUENCE
;
1159 op
->op
= FILTER_OP_LOAD_FIELD_REF_STRING
;
1162 op
->op
= FILTER_OP_LOAD_FIELD_REF_DOUBLE
;
1168 field_ref
->offset
= (uint16_t) field_offset
;
1173 * Take a bytecode with reloc table and link it to an event to create a
1177 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1178 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1180 int ret
, offset
, next_offset
;
1181 struct bytecode_runtime
*runtime
= NULL
;
1182 size_t runtime_alloc_len
;
1184 if (!filter_bytecode
)
1186 /* Even is not connected to any description */
1189 /* Bytecode already linked */
1190 if (event
->filter
|| event
->filter_data
)
1193 dbg_printf("Linking\n");
1195 /* We don't need the reloc table in the runtime */
1196 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
1197 runtime
= zmalloc(runtime_alloc_len
);
1202 runtime
->len
= filter_bytecode
->reloc_offset
;
1203 /* copy original bytecode */
1204 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
1206 * apply relocs. Those are a uint16_t (offset in bytecode)
1207 * followed by a string (field name).
1209 for (offset
= filter_bytecode
->reloc_offset
;
1210 offset
< filter_bytecode
->len
;
1211 offset
= next_offset
) {
1212 uint16_t reloc_offset
=
1213 *(uint16_t *) &filter_bytecode
->data
[offset
];
1214 const char *field_name
=
1215 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
1217 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1221 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1223 /* Validate bytecode */
1224 ret
= lttng_filter_validate_bytecode(runtime
);
1228 event
->filter_data
= runtime
;
1229 event
->filter
= lttng_filter_interpret_bytecode
;
1233 event
->filter
= lttng_filter_false
;
1238 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1239 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1243 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1245 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1250 * Link bytecode to all events for a wildcard. Skips events that already
1251 * have a bytecode linked.
1252 * We do not set each event's filter_bytecode field, because they do not
1253 * own the filter_bytecode: the wildcard owns it.
1255 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1257 struct ltt_event
*event
;
1260 if (!wildcard
->filter_bytecode
)
1263 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1266 ret
= _lttng_filter_event_link_bytecode(event
,
1267 wildcard
->filter_bytecode
);
1269 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1277 * Need to attach filter to an event before starting tracing for the
1278 * session. We own the filter_bytecode if we return success.
1280 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1281 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1283 if (event
->chan
->session
->been_active
)
1285 if (event
->filter_bytecode
)
1287 event
->filter_bytecode
= filter_bytecode
;
1292 * Need to attach filter to a wildcard before starting tracing for the
1293 * session. We own the filter_bytecode if we return success.
1295 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1296 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1298 if (wildcard
->chan
->session
->been_active
)
1300 if (wildcard
->filter_bytecode
)
1302 wildcard
->filter_bytecode
= filter_bytecode
;