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_FIELD_REF_STRING
] = "LOAD_FIELD_REF_STRING",
125 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = "LOAD_FIELD_REF_SEQUENCE",
126 [ FILTER_OP_LOAD_FIELD_REF_S64
] = "LOAD_FIELD_REF_S64",
127 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = "LOAD_FIELD_REF_DOUBLE",
129 [ FILTER_OP_LOAD_STRING
] = "LOAD_STRING",
130 [ FILTER_OP_LOAD_S64
] = "LOAD_S64",
131 [ FILTER_OP_LOAD_DOUBLE
] = "LOAD_DOUBLE",
135 const char *print_op(enum filter_op op
)
137 if (op
>= NR_FILTER_OPS
)
144 * -1: wildcard found.
145 * -2: unknown escape char.
150 int parse_char(const char **p
)
170 int reg_strcmp(struct reg reg
[NR_REG
], const char *cmp_type
)
172 const char *p
= reg
[REG_R0
].str
, *q
= reg
[REG_R1
].str
;
179 if (unlikely(p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')) {
180 if (q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')
186 if (unlikely(q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')) {
187 if (p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')
193 if (reg
[REG_R0
].literal
) {
194 ret
= parse_char(&p
);
197 } else if (ret
== -2) {
200 /* else compare both char */
202 if (reg
[REG_R1
].literal
) {
203 ret
= parse_char(&q
);
206 } else if (ret
== -2) {
227 int lttng_filter_false(void *filter_data
,
228 const char *filter_stack_data
)
234 int lttng_filter_interpret_bytecode(void *filter_data
,
235 const char *filter_stack_data
)
237 struct bytecode_runtime
*bytecode
= filter_data
;
238 void *pc
, *next_pc
, *start_pc
;
241 struct reg reg
[NR_REG
];
244 for (i
= 0; i
< NR_REG
; i
++) {
245 reg
[i
].type
= REG_S64
;
253 start_pc
= &bytecode
->data
[0];
254 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
256 dbg_printf("Executing op %s (%u)\n",
257 print_op((unsigned int) *(filter_opcode_t
*) pc
),
258 (unsigned int) *(filter_opcode_t
*) pc
);
259 switch (*(filter_opcode_t
*) pc
) {
260 case FILTER_OP_UNKNOWN
:
261 case FILTER_OP_LOAD_FIELD_REF
:
263 ERR("unknown bytecode op %u\n",
264 (unsigned int) *(filter_opcode_t
*) pc
);
268 case FILTER_OP_RETURN
:
278 case FILTER_OP_MINUS
:
279 case FILTER_OP_RSHIFT
:
280 case FILTER_OP_LSHIFT
:
281 case FILTER_OP_BIN_AND
:
282 case FILTER_OP_BIN_OR
:
283 case FILTER_OP_BIN_XOR
:
284 ERR("unsupported bytecode op %u\n",
285 (unsigned int) *(filter_opcode_t
*) pc
);
291 switch (reg
[REG_R0
].type
) {
293 ERR("unknown register type\n");
298 reg
[REG_R0
].v
= (reg_strcmp(reg
, "==") == 0);
301 switch (reg
[REG_R1
].type
) {
303 ERR("unknown register type\n");
308 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].v
);
311 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].d
);
316 switch (reg
[REG_R1
].type
) {
318 ERR("unknown register type\n");
323 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].v
);
326 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].d
);
331 reg
[REG_R0
].type
= REG_S64
;
332 next_pc
+= sizeof(struct binary_op
);
337 switch (reg
[REG_R0
].type
) {
339 ERR("unknown register type\n");
344 reg
[REG_R0
].v
= (reg_strcmp(reg
, "!=") != 0);
347 switch (reg
[REG_R1
].type
) {
349 ERR("unknown register type\n");
354 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].v
);
357 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].d
);
362 switch (reg
[REG_R1
].type
) {
364 ERR("unknown register type\n");
369 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].v
);
372 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].d
);
377 reg
[REG_R0
].type
= REG_S64
;
378 next_pc
+= sizeof(struct binary_op
);
383 switch (reg
[REG_R0
].type
) {
385 ERR("unknown register type\n");
390 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">") > 0);
393 switch (reg
[REG_R1
].type
) {
395 ERR("unknown register type\n");
400 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].v
);
403 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].d
);
408 switch (reg
[REG_R1
].type
) {
410 ERR("unknown register type\n");
415 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].v
);
418 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].d
);
423 reg
[REG_R0
].type
= REG_S64
;
424 next_pc
+= sizeof(struct binary_op
);
429 switch (reg
[REG_R0
].type
) {
431 ERR("unknown register type\n");
436 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<") < 0);
439 switch (reg
[REG_R1
].type
) {
441 ERR("unknown register type\n");
446 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].v
);
449 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].d
);
454 switch (reg
[REG_R1
].type
) {
456 ERR("unknown register type\n");
461 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].v
);
464 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].d
);
469 reg
[REG_R0
].type
= REG_S64
;
470 next_pc
+= sizeof(struct binary_op
);
475 switch (reg
[REG_R0
].type
) {
477 ERR("unknown register type\n");
482 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">=") >= 0);
485 switch (reg
[REG_R1
].type
) {
487 ERR("unknown register type\n");
492 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].v
);
495 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].d
);
500 switch (reg
[REG_R1
].type
) {
502 ERR("unknown register type\n");
507 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].v
);
510 reg
[REG_R0
].v
= (reg
[REG_R0
].d
>= reg
[REG_R1
].d
);
515 reg
[REG_R0
].type
= REG_S64
;
516 next_pc
+= sizeof(struct binary_op
);
521 switch (reg
[REG_R0
].type
) {
523 ERR("unknown register type\n");
528 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<=") <= 0);
531 switch (reg
[REG_R1
].type
) {
533 ERR("unknown register type\n");
538 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].v
);
541 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].d
);
546 switch (reg
[REG_R1
].type
) {
548 ERR("unknown register type\n");
553 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].v
);
556 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].d
);
561 reg
[REG_R0
].type
= REG_S64
;
562 next_pc
+= sizeof(struct binary_op
);
567 case FILTER_OP_UNARY_PLUS
:
569 next_pc
+= sizeof(struct unary_op
);
572 case FILTER_OP_UNARY_MINUS
:
574 struct unary_op
*insn
= (struct unary_op
*) pc
;
576 switch (reg
[insn
->reg
].type
) {
578 ERR("unknown register type\n");
583 ERR("Unary minus can only be applied to numeric or floating point registers\n");
587 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
590 reg
[insn
->reg
].d
= -reg
[insn
->reg
].d
;
593 next_pc
+= sizeof(struct unary_op
);
596 case FILTER_OP_UNARY_NOT
:
598 struct unary_op
*insn
= (struct unary_op
*) pc
;
600 switch (reg
[insn
->reg
].type
) {
602 ERR("unknown register type\n");
607 ERR("Unary not can only be applied to numeric or floating point registers\n");
611 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
614 reg
[insn
->reg
].d
= !reg
[insn
->reg
].d
;
617 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
618 next_pc
+= sizeof(struct unary_op
);
624 struct logical_op
*insn
= (struct logical_op
*) pc
;
626 /* If REG_R0 is 0, skip and evaluate to 0 */
627 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
== 0)
628 || (reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
== 0.0)) {
629 dbg_printf("Jumping to bytecode offset %u\n",
630 (unsigned int) insn
->skip_offset
);
631 next_pc
= start_pc
+ insn
->skip_offset
;
633 next_pc
+= sizeof(struct logical_op
);
639 struct logical_op
*insn
= (struct logical_op
*) pc
;
641 /* If REG_R0 is nonzero, skip and evaluate to 1 */
643 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
!= 0)
644 || (reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
!= 0.0)) {
646 dbg_printf("Jumping to bytecode offset %u\n",
647 (unsigned int) insn
->skip_offset
);
648 next_pc
= start_pc
+ insn
->skip_offset
;
650 next_pc
+= sizeof(struct logical_op
);
656 case FILTER_OP_LOAD_FIELD_REF_STRING
:
658 struct load_op
*insn
= (struct load_op
*) pc
;
659 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
661 dbg_printf("load field ref offset %u type string\n",
664 *(const char * const *) &filter_stack_data
[ref
->offset
];
665 reg
[insn
->reg
].type
= REG_STRING
;
666 reg
[insn
->reg
].seq_len
= UINT_MAX
;
667 reg
[insn
->reg
].literal
= 0;
668 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
669 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
673 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
675 struct load_op
*insn
= (struct load_op
*) pc
;
676 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
678 dbg_printf("load field ref offset %u type sequence\n",
680 reg
[insn
->reg
].seq_len
=
681 *(unsigned long *) &filter_stack_data
[ref
->offset
];
683 *(const char **) (&filter_stack_data
[ref
->offset
684 + sizeof(unsigned long)]);
685 reg
[insn
->reg
].type
= REG_STRING
;
686 reg
[insn
->reg
].literal
= 0;
687 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
691 case FILTER_OP_LOAD_FIELD_REF_S64
:
693 struct load_op
*insn
= (struct load_op
*) pc
;
694 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
696 dbg_printf("load field ref offset %u type s64\n",
698 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
699 sizeof(struct literal_numeric
));
700 reg
[insn
->reg
].type
= REG_S64
;
701 reg
[insn
->reg
].literal
= 0;
702 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
703 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
707 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
709 struct load_op
*insn
= (struct load_op
*) pc
;
710 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
712 dbg_printf("load field ref offset %u type double\n",
714 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
715 sizeof(struct literal_double
));
716 reg
[insn
->reg
].type
= REG_DOUBLE
;
717 reg
[insn
->reg
].literal
= 0;
718 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
719 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
723 case FILTER_OP_LOAD_STRING
:
725 struct load_op
*insn
= (struct load_op
*) pc
;
727 dbg_printf("load string %s\n", insn
->data
);
728 reg
[insn
->reg
].str
= insn
->data
;
729 reg
[insn
->reg
].type
= REG_STRING
;
730 reg
[insn
->reg
].seq_len
= UINT_MAX
;
731 reg
[insn
->reg
].literal
= 1;
732 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
736 case FILTER_OP_LOAD_S64
:
738 struct load_op
*insn
= (struct load_op
*) pc
;
740 memcpy(®
[insn
->reg
].v
, insn
->data
,
741 sizeof(struct literal_numeric
));
742 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
743 reg
[insn
->reg
].type
= REG_S64
;
744 next_pc
+= sizeof(struct load_op
)
745 + sizeof(struct literal_numeric
);
749 case FILTER_OP_LOAD_DOUBLE
:
751 struct load_op
*insn
= (struct load_op
*) pc
;
753 memcpy(®
[insn
->reg
].d
, insn
->data
,
754 sizeof(struct literal_double
));
755 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
756 reg
[insn
->reg
].type
= REG_DOUBLE
;
757 next_pc
+= sizeof(struct load_op
)
758 + sizeof(struct literal_double
);
764 /* return 0 (discard) on error */
771 int bin_op_compare_check(struct vreg reg
[NR_REG
], const char *str
)
773 switch (reg
[REG_R0
].type
) {
778 switch (reg
[REG_R1
].type
) {
791 switch (reg
[REG_R1
].type
) {
810 ERR("type mismatch for '%s' binary operator\n", str
);
815 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
817 void *pc
, *next_pc
, *start_pc
;
819 struct vreg reg
[NR_REG
];
822 for (i
= 0; i
< NR_REG
; i
++) {
823 reg
[i
].type
= REG_S64
;
827 start_pc
= &bytecode
->data
[0];
828 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
830 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
831 ERR("filter bytecode overflow\n");
835 dbg_printf("Validating op %s (%u)\n",
836 print_op((unsigned int) *(filter_opcode_t
*) pc
),
837 (unsigned int) *(filter_opcode_t
*) pc
);
838 switch (*(filter_opcode_t
*) pc
) {
839 case FILTER_OP_UNKNOWN
:
841 ERR("unknown bytecode op %u\n",
842 (unsigned int) *(filter_opcode_t
*) pc
);
846 case FILTER_OP_RETURN
:
855 case FILTER_OP_MINUS
:
856 case FILTER_OP_RSHIFT
:
857 case FILTER_OP_LSHIFT
:
858 case FILTER_OP_BIN_AND
:
859 case FILTER_OP_BIN_OR
:
860 case FILTER_OP_BIN_XOR
:
861 ERR("unsupported bytecode op %u\n",
862 (unsigned int) *(filter_opcode_t
*) pc
);
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 ret
= bin_op_compare_check(reg
, "<=");
916 reg
[REG_R0
].type
= REG_S64
;
917 next_pc
+= sizeof(struct binary_op
);
922 case FILTER_OP_UNARY_PLUS
:
923 case FILTER_OP_UNARY_MINUS
:
924 case FILTER_OP_UNARY_NOT
:
926 struct unary_op
*insn
= (struct unary_op
*) pc
;
928 if (unlikely(insn
->reg
>= REG_ERROR
)) {
929 ERR("invalid register %u\n",
930 (unsigned int) insn
->reg
);
934 switch (reg
[insn
->reg
].type
) {
936 ERR("unknown register type\n");
941 ERR("Unary op can only be applied to numeric or floating point registers\n");
949 next_pc
+= sizeof(struct unary_op
);
956 struct logical_op
*insn
= (struct logical_op
*) pc
;
958 if (unlikely(reg
[REG_R0
].type
== REG_STRING
)) {
959 ERR("Logical operator 'and' can only be applied to numeric and floating point registers\n");
964 dbg_printf("Validate jumping to bytecode offset %u\n",
965 (unsigned int) insn
->skip_offset
);
966 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
967 ERR("Loops are not allowed in bytecode\n");
971 next_pc
+= sizeof(struct logical_op
);
976 case FILTER_OP_LOAD_FIELD_REF
:
978 ERR("Unknown field ref type\n");
982 case FILTER_OP_LOAD_FIELD_REF_STRING
:
983 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
985 struct load_op
*insn
= (struct load_op
*) pc
;
986 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
988 if (unlikely(insn
->reg
>= REG_ERROR
)) {
989 ERR("invalid register %u\n",
990 (unsigned int) insn
->reg
);
994 dbg_printf("Validate load field ref offset %u type string\n",
996 reg
[insn
->reg
].type
= REG_STRING
;
997 reg
[insn
->reg
].literal
= 0;
998 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1001 case FILTER_OP_LOAD_FIELD_REF_S64
:
1003 struct load_op
*insn
= (struct load_op
*) pc
;
1004 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1006 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1007 ERR("invalid register %u\n",
1008 (unsigned int) insn
->reg
);
1012 dbg_printf("Validate load field ref offset %u type s64\n",
1014 reg
[insn
->reg
].type
= REG_S64
;
1015 reg
[insn
->reg
].literal
= 0;
1016 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1019 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1021 struct load_op
*insn
= (struct load_op
*) pc
;
1022 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1024 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1025 ERR("invalid register %u\n",
1026 (unsigned int) insn
->reg
);
1030 dbg_printf("Validate load field ref offset %u type double\n",
1032 reg
[insn
->reg
].type
= REG_DOUBLE
;
1033 reg
[insn
->reg
].literal
= 0;
1034 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1038 case FILTER_OP_LOAD_STRING
:
1040 struct load_op
*insn
= (struct load_op
*) pc
;
1042 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1043 ERR("invalid register %u\n",
1044 (unsigned int) insn
->reg
);
1048 reg
[insn
->reg
].type
= REG_STRING
;
1049 reg
[insn
->reg
].literal
= 1;
1050 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1054 case FILTER_OP_LOAD_S64
:
1056 struct load_op
*insn
= (struct load_op
*) pc
;
1058 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1059 ERR("invalid register %u\n",
1060 (unsigned int) insn
->reg
);
1064 reg
[insn
->reg
].type
= REG_S64
;
1065 next_pc
+= sizeof(struct load_op
)
1066 + sizeof(struct literal_numeric
);
1070 case FILTER_OP_LOAD_DOUBLE
:
1072 struct load_op
*insn
= (struct load_op
*) pc
;
1074 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1075 ERR("invalid register %u\n",
1076 (unsigned int) insn
->reg
);
1080 reg
[insn
->reg
].type
= REG_DOUBLE
;
1081 next_pc
+= sizeof(struct load_op
)
1082 + sizeof(struct literal_double
);
1092 int apply_field_reloc(struct ltt_event
*event
,
1093 struct bytecode_runtime
*runtime
,
1094 uint32_t runtime_len
,
1095 uint32_t reloc_offset
,
1096 const char *field_name
)
1098 const struct lttng_event_desc
*desc
;
1099 const struct lttng_event_field
*fields
, *field
= NULL
;
1100 unsigned int nr_fields
, i
;
1101 struct field_ref
*field_ref
;
1103 uint32_t field_offset
= 0;
1105 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1107 /* Ensure that the reloc is within the code */
1108 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1111 /* Lookup event by name */
1115 fields
= desc
->fields
;
1118 nr_fields
= desc
->nr_fields
;
1119 for (i
= 0; i
< nr_fields
; i
++) {
1120 if (!strcmp(fields
[i
].name
, field_name
)) {
1124 /* compute field offset */
1125 switch (fields
[i
].type
.atype
) {
1128 field_offset
+= sizeof(int64_t);
1131 case atype_sequence
:
1132 field_offset
+= sizeof(unsigned long);
1133 field_offset
+= sizeof(void *);
1136 field_offset
+= sizeof(void *);
1139 field_offset
+= sizeof(double);
1148 /* Check if field offset is too large for 16-bit offset */
1149 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1153 op
= (struct load_op
*) &runtime
->data
[reloc_offset
];
1154 field_ref
= (struct field_ref
*) op
->data
;
1155 switch (field
->type
.atype
) {
1158 op
->op
= FILTER_OP_LOAD_FIELD_REF_S64
;
1161 case atype_sequence
:
1162 op
->op
= FILTER_OP_LOAD_FIELD_REF_SEQUENCE
;
1165 op
->op
= FILTER_OP_LOAD_FIELD_REF_STRING
;
1168 op
->op
= FILTER_OP_LOAD_FIELD_REF_DOUBLE
;
1174 field_ref
->offset
= (uint16_t) field_offset
;
1179 * Take a bytecode with reloc table and link it to an event to create a
1183 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1184 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1186 int ret
, offset
, next_offset
;
1187 struct bytecode_runtime
*runtime
= NULL
;
1188 size_t runtime_alloc_len
;
1190 if (!filter_bytecode
)
1192 /* Even is not connected to any description */
1195 /* Bytecode already linked */
1196 if (event
->filter
|| event
->filter_data
)
1199 dbg_printf("Linking\n");
1201 /* We don't need the reloc table in the runtime */
1202 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
1203 runtime
= zmalloc(runtime_alloc_len
);
1208 runtime
->len
= filter_bytecode
->reloc_offset
;
1209 /* copy original bytecode */
1210 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
1212 * apply relocs. Those are a uint16_t (offset in bytecode)
1213 * followed by a string (field name).
1215 for (offset
= filter_bytecode
->reloc_offset
;
1216 offset
< filter_bytecode
->len
;
1217 offset
= next_offset
) {
1218 uint16_t reloc_offset
=
1219 *(uint16_t *) &filter_bytecode
->data
[offset
];
1220 const char *field_name
=
1221 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
1223 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1227 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1229 /* Validate bytecode */
1230 ret
= lttng_filter_validate_bytecode(runtime
);
1234 event
->filter_data
= runtime
;
1235 event
->filter
= lttng_filter_interpret_bytecode
;
1239 event
->filter
= lttng_filter_false
;
1244 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1245 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1249 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1251 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1256 * Link bytecode to all events for a wildcard. Skips events that already
1257 * have a bytecode linked.
1258 * We do not set each event's filter_bytecode field, because they do not
1259 * own the filter_bytecode: the wildcard owns it.
1261 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1263 struct ltt_event
*event
;
1266 if (!wildcard
->filter_bytecode
)
1269 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1272 ret
= _lttng_filter_event_link_bytecode(event
,
1273 wildcard
->filter_bytecode
);
1275 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1283 * Need to attach filter to an event before starting tracing for the
1284 * session. We own the filter_bytecode if we return success.
1286 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1287 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1289 if (event
->chan
->session
->been_active
)
1291 if (event
->filter_bytecode
)
1293 event
->filter_bytecode
= filter_bytecode
;
1298 * Need to attach filter to a wildcard before starting tracing for the
1299 * session. We own the filter_bytecode if we return success.
1301 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1302 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1304 if (wildcard
->chan
->session
->been_active
)
1306 if (wildcard
->filter_bytecode
)
1308 wildcard
->filter_bytecode
= filter_bytecode
;