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
{
73 /* Validation registers */
76 int literal
; /* is string literal ? */
79 /* Execution registers */
87 int literal
; /* is string literal ? */
90 static const char *opnames
[] = {
91 [ FILTER_OP_UNKNOWN
] = "UNKNOWN",
93 [ FILTER_OP_RETURN
] = "RETURN",
96 [ FILTER_OP_MUL
] = "MUL",
97 [ FILTER_OP_DIV
] = "DIV",
98 [ FILTER_OP_MOD
] = "MOD",
99 [ FILTER_OP_PLUS
] = "PLUS",
100 [ FILTER_OP_MINUS
] = "MINUS",
101 [ FILTER_OP_RSHIFT
] = "RSHIFT",
102 [ FILTER_OP_LSHIFT
] = "LSHIFT",
103 [ FILTER_OP_BIN_AND
] = "BIN_AND",
104 [ FILTER_OP_BIN_OR
] = "BIN_OR",
105 [ FILTER_OP_BIN_XOR
] = "BIN_XOR",
106 [ FILTER_OP_EQ
] = "EQ",
107 [ FILTER_OP_NE
] = "NE",
108 [ FILTER_OP_GT
] = "GT",
109 [ FILTER_OP_LT
] = "LT",
110 [ FILTER_OP_GE
] = "GE",
111 [ FILTER_OP_LE
] = "LE",
114 [ FILTER_OP_UNARY_PLUS
] = "UNARY_PLUS",
115 [ FILTER_OP_UNARY_MINUS
] = "UNARY_MINUS",
116 [ FILTER_OP_UNARY_NOT
] = "UNARY_NOT",
119 [ FILTER_OP_AND
] = "AND",
120 [ FILTER_OP_OR
] = "OR",
123 [ FILTER_OP_LOAD_FIELD_REF
] = "LOAD_FIELD_REF",
124 [ FILTER_OP_LOAD_STRING
] = "LOAD_STRING",
125 [ FILTER_OP_LOAD_S64
] = "LOAD_S64",
126 [ FILTER_OP_LOAD_DOUBLE
] = "LOAD_DOUBLE",
130 const char *print_op(enum filter_op op
)
132 if (op
>= NR_FILTER_OPS
)
139 * -1: wildcard found.
140 * -2: unknown escape char.
145 int parse_char(const char **p
)
165 int reg_strcmp(struct reg reg
[NR_REG
], const char *cmp_type
)
167 const char *p
= reg
[REG_R0
].str
, *q
= reg
[REG_R1
].str
;
174 if (unlikely(p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')) {
175 if (q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')
181 if (unlikely(q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')) {
182 if (p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')
188 if (reg
[REG_R0
].literal
) {
189 ret
= parse_char(&p
);
192 } else if (ret
== -2) {
195 /* else compare both char */
197 if (reg
[REG_R1
].literal
) {
198 ret
= parse_char(&q
);
201 } else if (ret
== -2) {
222 int lttng_filter_false(void *filter_data
,
223 const char *filter_stack_data
)
229 int lttng_filter_interpret_bytecode(void *filter_data
,
230 const char *filter_stack_data
)
232 struct bytecode_runtime
*bytecode
= filter_data
;
233 void *pc
, *next_pc
, *start_pc
;
236 struct reg reg
[NR_REG
];
239 for (i
= 0; i
< NR_REG
; i
++) {
240 reg
[i
].type
= REG_S64
;
248 start_pc
= &bytecode
->data
[0];
249 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
251 dbg_printf("Executing op %s (%u)\n",
252 print_op((unsigned int) *(filter_opcode_t
*) pc
),
253 (unsigned int) *(filter_opcode_t
*) pc
);
254 switch (*(filter_opcode_t
*) pc
) {
255 case FILTER_OP_UNKNOWN
:
257 ERR("unknown bytecode op %u\n",
258 (unsigned int) *(filter_opcode_t
*) pc
);
262 case FILTER_OP_RETURN
:
272 case FILTER_OP_MINUS
:
273 case FILTER_OP_RSHIFT
:
274 case FILTER_OP_LSHIFT
:
275 case FILTER_OP_BIN_AND
:
276 case FILTER_OP_BIN_OR
:
277 case FILTER_OP_BIN_XOR
:
278 ERR("unsupported bytecode op %u\n",
279 (unsigned int) *(filter_opcode_t
*) pc
);
285 switch (reg
[REG_R0
].type
) {
287 ERR("unknown register type\n");
292 reg
[REG_R0
].v
= (reg_strcmp(reg
, "==") == 0);
295 switch (reg
[REG_R1
].type
) {
297 ERR("unknown register type\n");
302 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].v
);
305 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].d
);
310 switch (reg
[REG_R1
].type
) {
312 ERR("unknown register type\n");
317 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].v
);
320 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].d
);
325 reg
[REG_R0
].type
= REG_S64
;
326 next_pc
+= sizeof(struct binary_op
);
331 switch (reg
[REG_R0
].type
) {
333 ERR("unknown register type\n");
338 reg
[REG_R0
].v
= (reg_strcmp(reg
, "!=") != 0);
341 switch (reg
[REG_R1
].type
) {
343 ERR("unknown register type\n");
348 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].v
);
351 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].d
);
356 switch (reg
[REG_R1
].type
) {
358 ERR("unknown register type\n");
363 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].v
);
366 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].d
);
371 reg
[REG_R0
].type
= REG_S64
;
372 next_pc
+= sizeof(struct binary_op
);
377 switch (reg
[REG_R0
].type
) {
379 ERR("unknown register type\n");
384 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">") > 0);
387 switch (reg
[REG_R1
].type
) {
389 ERR("unknown register type\n");
394 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].v
);
397 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].d
);
402 switch (reg
[REG_R1
].type
) {
404 ERR("unknown register type\n");
409 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].v
);
412 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].d
);
417 reg
[REG_R0
].type
= REG_S64
;
418 next_pc
+= sizeof(struct binary_op
);
423 switch (reg
[REG_R0
].type
) {
425 ERR("unknown register type\n");
430 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<") < 0);
433 switch (reg
[REG_R1
].type
) {
435 ERR("unknown register type\n");
440 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].v
);
443 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].d
);
448 switch (reg
[REG_R1
].type
) {
450 ERR("unknown register type\n");
455 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].v
);
458 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].d
);
463 reg
[REG_R0
].type
= REG_S64
;
464 next_pc
+= sizeof(struct binary_op
);
469 switch (reg
[REG_R0
].type
) {
471 ERR("unknown register type\n");
476 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">=") >= 0);
479 switch (reg
[REG_R1
].type
) {
481 ERR("unknown register type\n");
486 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].v
);
489 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].d
);
494 switch (reg
[REG_R1
].type
) {
496 ERR("unknown register type\n");
501 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].v
);
504 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].d
);
509 reg
[REG_R0
].type
= REG_S64
;
510 next_pc
+= sizeof(struct binary_op
);
515 switch (reg
[REG_R0
].type
) {
517 ERR("unknown register type\n");
522 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<=") <= 0);
525 switch (reg
[REG_R1
].type
) {
527 ERR("unknown register type\n");
532 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].v
);
535 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].d
);
540 switch (reg
[REG_R1
].type
) {
542 ERR("unknown register type\n");
547 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].v
);
550 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].d
);
555 reg
[REG_R0
].type
= REG_S64
;
556 next_pc
+= sizeof(struct binary_op
);
561 case FILTER_OP_UNARY_PLUS
:
563 next_pc
+= sizeof(struct unary_op
);
566 case FILTER_OP_UNARY_MINUS
:
568 struct unary_op
*insn
= (struct unary_op
*) pc
;
570 switch (reg
[insn
->reg
].type
) {
572 ERR("unknown register type\n");
577 ERR("Unary minus can only be applied to numeric or floating point registers\n");
581 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
584 reg
[insn
->reg
].d
= -reg
[insn
->reg
].d
;
587 next_pc
+= sizeof(struct unary_op
);
590 case FILTER_OP_UNARY_NOT
:
592 struct unary_op
*insn
= (struct unary_op
*) pc
;
594 switch (reg
[insn
->reg
].type
) {
596 ERR("unknown register type\n");
601 ERR("Unary not can only be applied to numeric or floating point registers\n");
605 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
608 reg
[insn
->reg
].d
= !reg
[insn
->reg
].d
;
611 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
612 next_pc
+= sizeof(struct unary_op
);
618 struct logical_op
*insn
= (struct logical_op
*) pc
;
620 /* If REG_R0 is 0, skip and evaluate to 0 */
621 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
== 0)
622 || (reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
== 0.0)) {
623 dbg_printf("Jumping to bytecode offset %u\n",
624 (unsigned int) insn
->skip_offset
);
625 next_pc
= start_pc
+ insn
->skip_offset
;
627 next_pc
+= sizeof(struct logical_op
);
633 struct logical_op
*insn
= (struct logical_op
*) pc
;
635 /* If REG_R0 is nonzero, skip and evaluate to 1 */
637 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
!= 0)
638 || (reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
!= 0.0)) {
640 dbg_printf("Jumping to bytecode offset %u\n",
641 (unsigned int) insn
->skip_offset
);
642 next_pc
= start_pc
+ insn
->skip_offset
;
644 next_pc
+= sizeof(struct logical_op
);
650 case FILTER_OP_LOAD_FIELD_REF
:
652 struct load_op
*insn
= (struct load_op
*) pc
;
653 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
655 dbg_printf("load field ref offset %u type %u\n",
656 ref
->offset
, ref
->type
);
658 case FIELD_REF_UNKNOWN
:
660 ERR("unknown field ref type\n");
664 case FIELD_REF_STRING
:
666 *(const char * const *) &filter_stack_data
[ref
->offset
];
667 reg
[insn
->reg
].type
= REG_STRING
;
668 reg
[insn
->reg
].seq_len
= UINT_MAX
;
669 reg
[insn
->reg
].literal
= 0;
670 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
672 case FIELD_REF_SEQUENCE
:
673 reg
[insn
->reg
].seq_len
=
674 *(unsigned long *) &filter_stack_data
[ref
->offset
];
676 *(const char **) (&filter_stack_data
[ref
->offset
677 + sizeof(unsigned long)]);
678 reg
[insn
->reg
].type
= REG_STRING
;
679 reg
[insn
->reg
].literal
= 0;
682 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
683 sizeof(struct literal_numeric
));
684 reg
[insn
->reg
].type
= REG_S64
;
685 reg
[insn
->reg
].literal
= 0;
686 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
688 case FIELD_REF_DOUBLE
:
689 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
690 sizeof(struct literal_double
));
691 reg
[insn
->reg
].type
= REG_DOUBLE
;
692 reg
[insn
->reg
].literal
= 0;
693 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
697 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
701 case FILTER_OP_LOAD_STRING
:
703 struct load_op
*insn
= (struct load_op
*) pc
;
705 dbg_printf("load string %s\n", insn
->data
);
706 reg
[insn
->reg
].str
= insn
->data
;
707 reg
[insn
->reg
].type
= REG_STRING
;
708 reg
[insn
->reg
].seq_len
= UINT_MAX
;
709 reg
[insn
->reg
].literal
= 1;
710 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
714 case FILTER_OP_LOAD_S64
:
716 struct load_op
*insn
= (struct load_op
*) pc
;
718 memcpy(®
[insn
->reg
].v
, insn
->data
,
719 sizeof(struct literal_numeric
));
720 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
721 reg
[insn
->reg
].type
= REG_S64
;
722 next_pc
+= sizeof(struct load_op
)
723 + sizeof(struct literal_numeric
);
727 case FILTER_OP_LOAD_DOUBLE
:
729 struct load_op
*insn
= (struct load_op
*) pc
;
731 memcpy(®
[insn
->reg
].d
, insn
->data
,
732 sizeof(struct literal_double
));
733 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
734 reg
[insn
->reg
].type
= REG_DOUBLE
;
735 next_pc
+= sizeof(struct load_op
)
736 + sizeof(struct literal_double
);
742 /* return 0 (discard) on error */
749 int bin_op_compare_check(struct vreg reg
[NR_REG
], const char *str
)
751 switch (reg
[REG_R0
].type
) {
756 switch (reg
[REG_R1
].type
) {
769 switch (reg
[REG_R1
].type
) {
788 ERR("type mismatch for '%s' binary operator\n", str
);
793 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
795 void *pc
, *next_pc
, *start_pc
;
797 struct vreg reg
[NR_REG
];
800 for (i
= 0; i
< NR_REG
; i
++) {
801 reg
[i
].type
= REG_S64
;
805 start_pc
= &bytecode
->data
[0];
806 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
808 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
809 ERR("filter bytecode overflow\n");
813 dbg_printf("Validating op %s (%u)\n",
814 print_op((unsigned int) *(filter_opcode_t
*) pc
),
815 (unsigned int) *(filter_opcode_t
*) pc
);
816 switch (*(filter_opcode_t
*) pc
) {
817 case FILTER_OP_UNKNOWN
:
819 ERR("unknown bytecode op %u\n",
820 (unsigned int) *(filter_opcode_t
*) pc
);
824 case FILTER_OP_RETURN
:
833 case FILTER_OP_MINUS
:
834 case FILTER_OP_RSHIFT
:
835 case FILTER_OP_LSHIFT
:
836 case FILTER_OP_BIN_AND
:
837 case FILTER_OP_BIN_OR
:
838 case FILTER_OP_BIN_XOR
:
839 ERR("unsupported bytecode op %u\n",
840 (unsigned int) *(filter_opcode_t
*) pc
);
846 ret
= bin_op_compare_check(reg
, "==");
849 reg
[REG_R0
].type
= REG_S64
;
850 next_pc
+= sizeof(struct binary_op
);
855 ret
= bin_op_compare_check(reg
, "!=");
858 reg
[REG_R0
].type
= REG_S64
;
859 next_pc
+= sizeof(struct binary_op
);
864 ret
= bin_op_compare_check(reg
, ">");
867 reg
[REG_R0
].type
= REG_S64
;
868 next_pc
+= sizeof(struct binary_op
);
873 ret
= bin_op_compare_check(reg
, "<");
876 reg
[REG_R0
].type
= REG_S64
;
877 next_pc
+= sizeof(struct binary_op
);
882 ret
= bin_op_compare_check(reg
, ">=");
885 reg
[REG_R0
].type
= REG_S64
;
886 next_pc
+= sizeof(struct binary_op
);
891 ret
= bin_op_compare_check(reg
, "<=");
894 reg
[REG_R0
].type
= REG_S64
;
895 next_pc
+= sizeof(struct binary_op
);
900 case FILTER_OP_UNARY_PLUS
:
901 case FILTER_OP_UNARY_MINUS
:
902 case FILTER_OP_UNARY_NOT
:
904 struct unary_op
*insn
= (struct unary_op
*) pc
;
906 if (unlikely(insn
->reg
>= REG_ERROR
)) {
907 ERR("invalid register %u\n",
908 (unsigned int) insn
->reg
);
912 switch (reg
[insn
->reg
].type
) {
914 ERR("unknown register type\n");
919 ERR("Unary op can only be applied to numeric or floating point registers\n");
927 next_pc
+= sizeof(struct unary_op
);
934 struct logical_op
*insn
= (struct logical_op
*) pc
;
936 if (unlikely(reg
[REG_R0
].type
== REG_STRING
)) {
937 ERR("Logical operator 'and' can only be applied to numeric and floating point registers\n");
942 dbg_printf("Validate jumping to bytecode offset %u\n",
943 (unsigned int) insn
->skip_offset
);
944 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
945 ERR("Loops are not allowed in bytecode\n");
949 next_pc
+= sizeof(struct logical_op
);
954 case FILTER_OP_LOAD_FIELD_REF
:
956 struct load_op
*insn
= (struct load_op
*) pc
;
957 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
959 if (unlikely(insn
->reg
>= REG_ERROR
)) {
960 ERR("invalid register %u\n",
961 (unsigned int) insn
->reg
);
965 dbg_printf("Validate load field ref offset %u type %u\n",
966 ref
->offset
, ref
->type
);
968 case FIELD_REF_UNKNOWN
:
970 ERR("unknown field ref type\n");
974 case FIELD_REF_STRING
:
975 reg
[insn
->reg
].type
= REG_STRING
;
976 reg
[insn
->reg
].literal
= 0;
978 case FIELD_REF_SEQUENCE
:
979 reg
[insn
->reg
].type
= REG_STRING
;
980 reg
[insn
->reg
].literal
= 0;
983 reg
[insn
->reg
].type
= REG_S64
;
984 reg
[insn
->reg
].literal
= 0;
986 case FIELD_REF_DOUBLE
:
987 reg
[insn
->reg
].type
= REG_DOUBLE
;
988 reg
[insn
->reg
].literal
= 0;
992 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
996 case FILTER_OP_LOAD_STRING
:
998 struct load_op
*insn
= (struct load_op
*) pc
;
1000 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1001 ERR("invalid register %u\n",
1002 (unsigned int) insn
->reg
);
1006 reg
[insn
->reg
].type
= REG_STRING
;
1007 reg
[insn
->reg
].literal
= 1;
1008 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1012 case FILTER_OP_LOAD_S64
:
1014 struct load_op
*insn
= (struct load_op
*) pc
;
1016 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1017 ERR("invalid register %u\n",
1018 (unsigned int) insn
->reg
);
1022 reg
[insn
->reg
].type
= REG_S64
;
1023 next_pc
+= sizeof(struct load_op
)
1024 + sizeof(struct literal_numeric
);
1028 case FILTER_OP_LOAD_DOUBLE
:
1030 struct load_op
*insn
= (struct load_op
*) pc
;
1032 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1033 ERR("invalid register %u\n",
1034 (unsigned int) insn
->reg
);
1038 reg
[insn
->reg
].type
= REG_DOUBLE
;
1039 next_pc
+= sizeof(struct load_op
)
1040 + sizeof(struct literal_double
);
1050 int apply_field_reloc(struct ltt_event
*event
,
1051 struct bytecode_runtime
*runtime
,
1052 uint32_t runtime_len
,
1053 uint32_t reloc_offset
,
1054 const char *field_name
)
1056 const struct lttng_event_desc
*desc
;
1057 const struct lttng_event_field
*fields
, *field
= NULL
;
1058 unsigned int nr_fields
, i
;
1059 struct field_ref
*field_ref
;
1060 uint32_t field_offset
= 0;
1062 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1064 /* Ensure that the reloc is within the code */
1065 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1068 /* Lookup event by name */
1072 fields
= desc
->fields
;
1075 nr_fields
= desc
->nr_fields
;
1076 for (i
= 0; i
< nr_fields
; i
++) {
1077 if (!strcmp(fields
[i
].name
, field_name
)) {
1081 /* compute field offset */
1082 switch (fields
[i
].type
.atype
) {
1085 field_offset
+= sizeof(int64_t);
1088 case atype_sequence
:
1089 field_offset
+= sizeof(unsigned long);
1090 field_offset
+= sizeof(void *);
1093 field_offset
+= sizeof(void *);
1096 field_offset
+= sizeof(double);
1105 /* Check if field offset is too large for 16-bit offset */
1106 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1110 field_ref
= (struct field_ref
*) &runtime
->data
[reloc_offset
];
1111 switch (field
->type
.atype
) {
1114 field_ref
->type
= FIELD_REF_S64
;
1115 field_ref
->type
= FIELD_REF_S64
;
1118 case atype_sequence
:
1119 field_ref
->type
= FIELD_REF_SEQUENCE
;
1122 field_ref
->type
= FIELD_REF_STRING
;
1125 field_ref
->type
= FIELD_REF_DOUBLE
;
1131 field_ref
->offset
= (uint16_t) field_offset
;
1136 * Take a bytecode with reloc table and link it to an event to create a
1140 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1141 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1143 int ret
, offset
, next_offset
;
1144 struct bytecode_runtime
*runtime
= NULL
;
1145 size_t runtime_alloc_len
;
1147 if (!filter_bytecode
)
1149 /* Even is not connected to any description */
1152 /* Bytecode already linked */
1153 if (event
->filter
|| event
->filter_data
)
1156 dbg_printf("Linking\n");
1158 /* We don't need the reloc table in the runtime */
1159 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
1160 runtime
= zmalloc(runtime_alloc_len
);
1165 runtime
->len
= filter_bytecode
->reloc_offset
;
1166 /* copy original bytecode */
1167 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
1169 * apply relocs. Those are a uint16_t (offset in bytecode)
1170 * followed by a string (field name).
1172 for (offset
= filter_bytecode
->reloc_offset
;
1173 offset
< filter_bytecode
->len
;
1174 offset
= next_offset
) {
1175 uint16_t reloc_offset
=
1176 *(uint16_t *) &filter_bytecode
->data
[offset
];
1177 const char *field_name
=
1178 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
1180 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1184 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1186 /* Validate bytecode */
1187 ret
= lttng_filter_validate_bytecode(runtime
);
1191 event
->filter_data
= runtime
;
1192 event
->filter
= lttng_filter_interpret_bytecode
;
1196 event
->filter
= lttng_filter_false
;
1201 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1202 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1206 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1208 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1213 * Link bytecode to all events for a wildcard. Skips events that already
1214 * have a bytecode linked.
1215 * We do not set each event's filter_bytecode field, because they do not
1216 * own the filter_bytecode: the wildcard owns it.
1218 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1220 struct ltt_event
*event
;
1223 if (!wildcard
->filter_bytecode
)
1226 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1229 ret
= _lttng_filter_event_link_bytecode(event
,
1230 wildcard
->filter_bytecode
);
1232 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1240 * Need to attach filter to an event before starting tracing for the
1241 * session. We own the filter_bytecode if we return success.
1243 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1244 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1246 if (event
->chan
->session
->been_active
)
1248 if (event
->filter_bytecode
)
1250 event
->filter_bytecode
= filter_bytecode
;
1255 * Need to attach filter to a wildcard before starting tracing for the
1256 * session. We own the filter_bytecode if we return success.
1258 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1259 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1261 if (wildcard
->chan
->session
->been_active
)
1263 if (wildcard
->filter_bytecode
)
1265 wildcard
->filter_bytecode
= filter_bytecode
;