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 "filter-bytecode.h"
39 #define min_t(type, a, b) \
40 ((type) (a) < (type) (b) ? (type) (a) : (type) (b))
44 #define likely(x) __builtin_expect(!!(x), 1)
48 #define unlikely(x) __builtin_expect(!!(x), 0)
52 #define dbg_printf(fmt, args...) printf("[debug bytecode] " fmt, ## args)
54 #define dbg_printf(fmt, args...) \
56 /* do nothing but check printf format */ \
58 printf("[debug bytecode] " fmt, ## args); \
63 struct bytecode_runtime
{
79 int literal
; /* is string literal ? */
82 static const char *opnames
[] = {
83 [ FILTER_OP_UNKNOWN
] = "UNKNOWN",
85 [ FILTER_OP_RETURN
] = "RETURN",
88 [ FILTER_OP_MUL
] = "MUL",
89 [ FILTER_OP_DIV
] = "DIV",
90 [ FILTER_OP_MOD
] = "MOD",
91 [ FILTER_OP_PLUS
] = "PLUS",
92 [ FILTER_OP_MINUS
] = "MINUS",
93 [ FILTER_OP_RSHIFT
] = "RSHIFT",
94 [ FILTER_OP_LSHIFT
] = "LSHIFT",
95 [ FILTER_OP_BIN_AND
] = "BIN_AND",
96 [ FILTER_OP_BIN_OR
] = "BIN_OR",
97 [ FILTER_OP_BIN_XOR
] = "BIN_XOR",
98 [ FILTER_OP_EQ
] = "EQ",
99 [ FILTER_OP_NE
] = "NE",
100 [ FILTER_OP_GT
] = "GT",
101 [ FILTER_OP_LT
] = "LT",
102 [ FILTER_OP_GE
] = "GE",
103 [ FILTER_OP_LE
] = "LE",
106 [ FILTER_OP_UNARY_PLUS
] = "UNARY_PLUS",
107 [ FILTER_OP_UNARY_MINUS
] = "UNARY_MINUS",
108 [ FILTER_OP_UNARY_NOT
] = "UNARY_NOT",
111 [ FILTER_OP_AND
] = "AND",
112 [ FILTER_OP_OR
] = "OR",
115 [ FILTER_OP_LOAD_FIELD_REF
] = "LOAD_FIELD_REF",
116 [ FILTER_OP_LOAD_STRING
] = "LOAD_STRING",
117 [ FILTER_OP_LOAD_S64
] = "LOAD_S64",
118 [ FILTER_OP_LOAD_DOUBLE
] = "LOAD_DOUBLE",
122 const char *print_op(enum filter_op op
)
124 if (op
>= NR_FILTER_OPS
)
131 * -1: wildcard found.
132 * -2: unknown escape char.
137 int parse_char(const char **p
)
157 int reg_strcmp(struct reg reg
[NR_REG
], const char *cmp_type
)
159 const char *p
= reg
[REG_R0
].str
, *q
= reg
[REG_R1
].str
;
166 if (unlikely(p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')) {
167 if (q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')
173 if (unlikely(q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')) {
174 if (p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')
180 if (reg
[REG_R0
].literal
) {
181 ret
= parse_char(&p
);
184 } else if (ret
== -2) {
187 /* else compare both char */
189 if (reg
[REG_R1
].literal
) {
190 ret
= parse_char(&q
);
193 } else if (ret
== -2) {
214 int lttng_filter_false(void *filter_data
,
215 const char *filter_stack_data
)
221 int lttng_filter_interpret_bytecode(void *filter_data
,
222 const char *filter_stack_data
)
224 struct bytecode_runtime
*bytecode
= filter_data
;
225 void *pc
, *next_pc
, *start_pc
;
228 struct reg reg
[NR_REG
];
231 for (i
= 0; i
< NR_REG
; i
++) {
232 reg
[i
].type
= REG_S64
;
240 start_pc
= &bytecode
->data
[0];
241 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
243 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
244 fprintf(stderr
, "[error] filter bytecode overflow\n");
248 dbg_printf("Executing op %s (%u)\n",
249 print_op((unsigned int) *(filter_opcode_t
*) pc
),
250 (unsigned int) *(filter_opcode_t
*) pc
);
251 switch (*(filter_opcode_t
*) pc
) {
252 case FILTER_OP_UNKNOWN
:
254 fprintf(stderr
, "[error] 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 fprintf(stderr
, "[error] unsupported bytecode op %u\n",
276 (unsigned int) *(filter_opcode_t
*) pc
);
282 if (unlikely((reg
[REG_R0
].type
== REG_STRING
&& reg
[REG_R1
].type
!= REG_STRING
)
283 || (reg
[REG_R0
].type
!= REG_STRING
&& reg
[REG_R1
].type
== REG_STRING
))) {
284 fprintf(stderr
, "[error] type mismatch for '==' binary operator\n");
288 switch (reg
[REG_R0
].type
) {
290 fprintf(stderr
, "[error] unknown register type\n");
295 reg
[REG_R0
].v
= (reg_strcmp(reg
, "==") == 0);
298 switch (reg
[REG_R1
].type
) {
300 fprintf(stderr
, "[error] unknown register type\n");
305 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].v
);
308 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].d
);
313 switch (reg
[REG_R1
].type
) {
315 fprintf(stderr
, "[error] unknown register type\n");
320 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].v
);
323 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].d
);
328 reg
[REG_R0
].type
= REG_S64
;
329 next_pc
+= sizeof(struct binary_op
);
334 if (unlikely((reg
[REG_R0
].type
== REG_STRING
&& reg
[REG_R1
].type
!= REG_STRING
)
335 || (reg
[REG_R0
].type
!= REG_STRING
&& reg
[REG_R1
].type
== REG_STRING
))) {
336 fprintf(stderr
, "[error] type mismatch for '!=' binary operator\n");
340 switch (reg
[REG_R0
].type
) {
342 fprintf(stderr
, "[error] unknown register type\n");
347 reg
[REG_R0
].v
= (reg_strcmp(reg
, "!=") != 0);
350 switch (reg
[REG_R1
].type
) {
352 fprintf(stderr
, "[error] unknown register type\n");
357 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].v
);
360 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].d
);
365 switch (reg
[REG_R1
].type
) {
367 fprintf(stderr
, "[error] unknown register type\n");
372 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].v
);
375 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].d
);
380 reg
[REG_R0
].type
= REG_S64
;
381 next_pc
+= sizeof(struct binary_op
);
386 if (unlikely((reg
[REG_R0
].type
== REG_STRING
&& reg
[REG_R1
].type
!= REG_STRING
)
387 || (reg
[REG_R0
].type
!= REG_STRING
&& reg
[REG_R1
].type
== REG_STRING
))) {
388 fprintf(stderr
, "[error] type mismatch for '>' binary operator\n");
392 switch (reg
[REG_R0
].type
) {
394 fprintf(stderr
, "[error] unknown register type\n");
399 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">") > 0);
402 switch (reg
[REG_R1
].type
) {
404 fprintf(stderr
, "[error] unknown register type\n");
409 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].v
);
412 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].d
);
417 switch (reg
[REG_R1
].type
) {
419 fprintf(stderr
, "[error] unknown register type\n");
424 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].v
);
427 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].d
);
432 reg
[REG_R0
].type
= REG_S64
;
433 next_pc
+= sizeof(struct binary_op
);
438 if (unlikely((reg
[REG_R0
].type
== REG_STRING
&& reg
[REG_R1
].type
!= REG_STRING
)
439 || (reg
[REG_R0
].type
!= REG_STRING
&& reg
[REG_R1
].type
== REG_STRING
))) {
440 fprintf(stderr
, "[error] type mismatch for '<' binary operator\n");
444 switch (reg
[REG_R0
].type
) {
446 fprintf(stderr
, "[error] unknown register type\n");
451 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<") < 0);
454 switch (reg
[REG_R1
].type
) {
456 fprintf(stderr
, "[error] unknown register type\n");
461 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].v
);
464 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].d
);
469 switch (reg
[REG_R1
].type
) {
471 fprintf(stderr
, "[error] unknown register type\n");
476 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].v
);
479 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].d
);
484 reg
[REG_R0
].type
= REG_S64
;
485 next_pc
+= sizeof(struct binary_op
);
490 if (unlikely((reg
[REG_R0
].type
== REG_STRING
&& reg
[REG_R1
].type
!= REG_STRING
)
491 || (reg
[REG_R0
].type
!= REG_STRING
&& reg
[REG_R1
].type
== REG_STRING
))) {
492 fprintf(stderr
, "[error] type mismatch for '>=' binary operator\n");
496 switch (reg
[REG_R0
].type
) {
498 fprintf(stderr
, "[error] unknown register type\n");
503 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">=") >= 0);
506 switch (reg
[REG_R1
].type
) {
508 fprintf(stderr
, "[error] unknown register type\n");
513 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].v
);
516 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].d
);
521 switch (reg
[REG_R1
].type
) {
523 fprintf(stderr
, "[error] unknown register type\n");
528 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].v
);
531 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].d
);
536 reg
[REG_R0
].type
= REG_S64
;
537 next_pc
+= sizeof(struct binary_op
);
542 if (unlikely((reg
[REG_R0
].type
== REG_STRING
&& reg
[REG_R1
].type
!= REG_STRING
)
543 || (reg
[REG_R0
].type
!= REG_STRING
&& reg
[REG_R1
].type
== REG_STRING
))) {
544 fprintf(stderr
, "[error] type mismatch for '<=' binary operator\n");
548 switch (reg
[REG_R0
].type
) {
550 fprintf(stderr
, "[error] unknown register type\n");
555 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<=") <= 0);
558 switch (reg
[REG_R1
].type
) {
560 fprintf(stderr
, "[error] unknown register type\n");
565 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].v
);
568 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].d
);
573 switch (reg
[REG_R1
].type
) {
575 fprintf(stderr
, "[error] unknown register type\n");
580 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].v
);
583 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].d
);
588 reg
[REG_R0
].type
= REG_S64
;
589 next_pc
+= sizeof(struct binary_op
);
594 case FILTER_OP_UNARY_PLUS
:
596 struct unary_op
*insn
= (struct unary_op
*) pc
;
598 if (unlikely(insn
->reg
>= REG_ERROR
)) {
599 fprintf(stderr
, "[error] invalid register %u\n",
600 (unsigned int) insn
->reg
);
604 switch (reg
[insn
->reg
].type
) {
606 fprintf(stderr
, "[error] unknown register type\n");
611 fprintf(stderr
, "[error] Unary plus can only be applied to numeric or floating point registers\n");
619 next_pc
+= sizeof(struct unary_op
);
622 case FILTER_OP_UNARY_MINUS
:
624 struct unary_op
*insn
= (struct unary_op
*) pc
;
626 if (unlikely(insn
->reg
>= REG_ERROR
)) {
627 fprintf(stderr
, "[error] invalid register %u\n",
628 (unsigned int) insn
->reg
);
632 switch (reg
[insn
->reg
].type
) {
634 fprintf(stderr
, "[error] unknown register type\n");
639 fprintf(stderr
, "[error] Unary minus can only be applied to numeric or floating point registers\n");
643 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
646 reg
[insn
->reg
].d
= -reg
[insn
->reg
].d
;
649 next_pc
+= sizeof(struct unary_op
);
652 case FILTER_OP_UNARY_NOT
:
654 struct unary_op
*insn
= (struct unary_op
*) pc
;
656 if (unlikely(insn
->reg
>= REG_ERROR
)) {
657 fprintf(stderr
, "[error] invalid register %u\n",
658 (unsigned int) insn
->reg
);
662 switch (reg
[insn
->reg
].type
) {
664 fprintf(stderr
, "[error] unknown register type\n");
669 fprintf(stderr
, "[error] Unary not can only be applied to numeric or floating point registers\n");
673 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
676 reg
[insn
->reg
].d
= !reg
[insn
->reg
].d
;
679 if (unlikely(reg
[insn
->reg
].type
!= REG_S64
)) {
680 fprintf(stderr
, "[error] Unary not can only be applied to numeric register\n");
684 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
685 next_pc
+= sizeof(struct unary_op
);
691 struct logical_op
*insn
= (struct logical_op
*) pc
;
693 if (unlikely(reg
[REG_R0
].type
== REG_STRING
)) {
694 fprintf(stderr
, "[error] Logical operator 'and' can only be applied to numeric and floating point registers\n");
699 /* If REG_R0 is 0, skip and evaluate to 0 */
700 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
== 0)
701 || (reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
== 0.0)) {
702 dbg_printf("Jumping to bytecode offset %u\n",
703 (unsigned int) insn
->skip_offset
);
704 next_pc
= start_pc
+ insn
->skip_offset
;
705 if (unlikely(next_pc
<= pc
)) {
706 fprintf(stderr
, "[error] Loops are not allowed in bytecode\n");
711 next_pc
+= sizeof(struct logical_op
);
717 struct logical_op
*insn
= (struct logical_op
*) pc
;
719 if (unlikely(reg
[REG_R0
].type
== REG_STRING
)) {
720 fprintf(stderr
, "[error] Logical operator 'or' can only be applied to numeric and floating point registers\n");
725 /* If REG_R0 is nonzero, skip and evaluate to 1 */
727 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
!= 0)
728 || (reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
!= 0.0)) {
730 dbg_printf("Jumping to bytecode offset %u\n",
731 (unsigned int) insn
->skip_offset
);
732 next_pc
= start_pc
+ insn
->skip_offset
;
733 if (unlikely(next_pc
<= pc
)) {
734 fprintf(stderr
, "[error] Loops are not allowed in bytecode\n");
739 next_pc
+= sizeof(struct logical_op
);
745 case FILTER_OP_LOAD_FIELD_REF
:
747 struct load_op
*insn
= (struct load_op
*) pc
;
748 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
750 if (unlikely(insn
->reg
>= REG_ERROR
)) {
751 fprintf(stderr
, "[error] invalid register %u\n",
752 (unsigned int) insn
->reg
);
756 dbg_printf("load field ref offset %u type %u\n",
757 ref
->offset
, ref
->type
);
759 case FIELD_REF_UNKNOWN
:
761 fprintf(stderr
, "[error] unknown field ref type\n");
765 case FIELD_REF_STRING
:
767 *(const char * const *) &filter_stack_data
[ref
->offset
];
768 reg
[insn
->reg
].type
= REG_STRING
;
769 reg
[insn
->reg
].seq_len
= UINT_MAX
;
770 reg
[insn
->reg
].literal
= 0;
771 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
773 case FIELD_REF_SEQUENCE
:
774 reg
[insn
->reg
].seq_len
=
775 *(unsigned long *) &filter_stack_data
[ref
->offset
];
777 *(const char **) (&filter_stack_data
[ref
->offset
778 + sizeof(unsigned long)]);
779 reg
[insn
->reg
].type
= REG_STRING
;
780 reg
[insn
->reg
].literal
= 0;
783 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
784 sizeof(struct literal_numeric
));
785 reg
[insn
->reg
].type
= REG_S64
;
786 reg
[insn
->reg
].literal
= 0;
787 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
789 case FIELD_REF_DOUBLE
:
790 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
791 sizeof(struct literal_double
));
792 reg
[insn
->reg
].type
= REG_DOUBLE
;
793 reg
[insn
->reg
].literal
= 0;
794 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
798 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
802 case FILTER_OP_LOAD_STRING
:
804 struct load_op
*insn
= (struct load_op
*) pc
;
806 if (unlikely(insn
->reg
>= REG_ERROR
)) {
807 fprintf(stderr
, "[error] invalid register %u\n",
808 (unsigned int) insn
->reg
);
812 dbg_printf("load string %s\n", insn
->data
);
813 reg
[insn
->reg
].str
= insn
->data
;
814 reg
[insn
->reg
].type
= REG_STRING
;
815 reg
[insn
->reg
].seq_len
= UINT_MAX
;
816 reg
[insn
->reg
].literal
= 1;
817 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
821 case FILTER_OP_LOAD_S64
:
823 struct load_op
*insn
= (struct load_op
*) pc
;
825 if (unlikely(insn
->reg
>= REG_ERROR
)) {
826 fprintf(stderr
, "[error] invalid register %u\n",
827 (unsigned int) insn
->reg
);
831 memcpy(®
[insn
->reg
].v
, insn
->data
,
832 sizeof(struct literal_numeric
));
833 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
834 reg
[insn
->reg
].type
= REG_S64
;
835 next_pc
+= sizeof(struct load_op
)
836 + sizeof(struct literal_numeric
);
840 case FILTER_OP_LOAD_DOUBLE
:
842 struct load_op
*insn
= (struct load_op
*) pc
;
844 if (unlikely(insn
->reg
>= REG_ERROR
)) {
845 fprintf(stderr
, "[error] invalid register %u\n",
846 (unsigned int) insn
->reg
);
850 memcpy(®
[insn
->reg
].d
, insn
->data
,
851 sizeof(struct literal_double
));
852 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
853 reg
[insn
->reg
].type
= REG_DOUBLE
;
854 next_pc
+= sizeof(struct load_op
)
855 + sizeof(struct literal_double
);
861 /* return 0 (discard) on error */
868 int apply_field_reloc(struct ltt_event
*event
,
869 struct bytecode_runtime
*runtime
,
870 uint32_t runtime_len
,
871 uint32_t reloc_offset
,
872 const char *field_name
)
874 const struct lttng_event_desc
*desc
;
875 const struct lttng_event_field
*fields
, *field
= NULL
;
876 unsigned int nr_fields
, i
;
877 struct field_ref
*field_ref
;
878 uint32_t field_offset
= 0;
880 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
882 /* Ensure that the reloc is within the code */
883 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
886 /* Lookup event by name */
890 fields
= desc
->fields
;
893 nr_fields
= desc
->nr_fields
;
894 for (i
= 0; i
< nr_fields
; i
++) {
895 if (!strcmp(fields
[i
].name
, field_name
)) {
899 /* compute field offset */
900 switch (fields
[i
].type
.atype
) {
903 field_offset
+= sizeof(int64_t);
907 field_offset
+= sizeof(unsigned long);
908 field_offset
+= sizeof(void *);
911 field_offset
+= sizeof(void *);
914 field_offset
+= sizeof(double);
923 /* Check if field offset is too large for 16-bit offset */
924 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
928 field_ref
= (struct field_ref
*) &runtime
->data
[reloc_offset
];
929 switch (field
->type
.atype
) {
932 field_ref
->type
= FIELD_REF_S64
;
933 field_ref
->type
= FIELD_REF_S64
;
937 field_ref
->type
= FIELD_REF_SEQUENCE
;
940 field_ref
->type
= FIELD_REF_STRING
;
943 field_ref
->type
= FIELD_REF_DOUBLE
;
949 field_ref
->offset
= (uint16_t) field_offset
;
954 * Take a bytecode with reloc table and link it to an event to create a
958 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
959 struct lttng_ust_filter_bytecode
*filter_bytecode
)
961 int ret
, offset
, next_offset
;
962 struct bytecode_runtime
*runtime
= NULL
;
963 size_t runtime_alloc_len
;
965 if (!filter_bytecode
)
967 /* Even is not connected to any description */
970 /* Bytecode already linked */
971 if (event
->filter
|| event
->filter_data
)
974 dbg_printf("Linking\n");
976 /* We don't need the reloc table in the runtime */
977 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
978 runtime
= zmalloc(runtime_alloc_len
);
983 runtime
->len
= filter_bytecode
->reloc_offset
;
984 /* copy original bytecode */
985 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
987 * apply relocs. Those are a uint16_t (offset in bytecode)
988 * followed by a string (field name).
990 for (offset
= filter_bytecode
->reloc_offset
;
991 offset
< filter_bytecode
->len
;
992 offset
= next_offset
) {
993 uint16_t reloc_offset
=
994 *(uint16_t *) &filter_bytecode
->data
[offset
];
995 const char *field_name
=
996 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
998 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1002 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1004 event
->filter_data
= runtime
;
1005 event
->filter
= lttng_filter_interpret_bytecode
;
1009 event
->filter
= lttng_filter_false
;
1014 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1015 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1019 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1021 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1026 * Link bytecode to all events for a wildcard. Skips events that already
1027 * have a bytecode linked.
1028 * We do not set each event's filter_bytecode field, because they do not
1029 * own the filter_bytecode: the wildcard owns it.
1031 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1033 struct ltt_event
*event
;
1036 if (!wildcard
->filter_bytecode
)
1039 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1042 ret
= _lttng_filter_event_link_bytecode(event
,
1043 wildcard
->filter_bytecode
);
1045 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1053 * Need to attach filter to an event before starting tracing for the
1054 * session. We own the filter_bytecode if we return success.
1056 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1057 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1059 if (event
->chan
->session
->been_active
)
1061 if (event
->filter_bytecode
)
1063 event
->filter_bytecode
= filter_bytecode
;
1068 * Need to attach filter to a wildcard before starting tracing for the
1069 * session. We own the filter_bytecode if we return success.
1071 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1072 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1074 if (wildcard
->chan
->session
->been_active
)
1076 if (wildcard
->filter_bytecode
)
1078 wildcard
->filter_bytecode
= filter_bytecode
;