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 reg
[insn
->reg
].literal
= 1;
736 next_pc
+= sizeof(struct load_op
)
737 + sizeof(struct literal_numeric
);
741 case FILTER_OP_LOAD_DOUBLE
:
743 struct load_op
*insn
= (struct load_op
*) pc
;
745 memcpy(®
[insn
->reg
].d
, insn
->data
,
746 sizeof(struct literal_double
));
747 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
748 reg
[insn
->reg
].type
= REG_DOUBLE
;
749 reg
[insn
->reg
].literal
= 1;
750 next_pc
+= sizeof(struct load_op
)
751 + sizeof(struct literal_double
);
757 /* return 0 (discard) on error */
764 int bin_op_compare_check(struct vreg reg
[NR_REG
], const char *str
)
766 switch (reg
[REG_R0
].type
) {
771 switch (reg
[REG_R1
].type
) {
784 switch (reg
[REG_R1
].type
) {
803 ERR("type mismatch for '%s' binary operator\n", str
);
808 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
810 void *pc
, *next_pc
, *start_pc
;
812 struct vreg reg
[NR_REG
];
815 for (i
= 0; i
< NR_REG
; i
++) {
816 reg
[i
].type
= REG_TYPE_UNKNOWN
;
820 start_pc
= &bytecode
->data
[0];
821 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
823 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
824 ERR("filter bytecode overflow\n");
828 dbg_printf("Validating op %s (%u)\n",
829 print_op((unsigned int) *(filter_opcode_t
*) pc
),
830 (unsigned int) *(filter_opcode_t
*) pc
);
831 switch (*(filter_opcode_t
*) pc
) {
832 case FILTER_OP_UNKNOWN
:
834 ERR("unknown bytecode op %u\n",
835 (unsigned int) *(filter_opcode_t
*) pc
);
839 case FILTER_OP_RETURN
:
848 case FILTER_OP_MINUS
:
849 case FILTER_OP_RSHIFT
:
850 case FILTER_OP_LSHIFT
:
851 case FILTER_OP_BIN_AND
:
852 case FILTER_OP_BIN_OR
:
853 case FILTER_OP_BIN_XOR
:
854 ERR("unsupported bytecode op %u\n",
855 (unsigned int) *(filter_opcode_t
*) pc
);
861 ret
= bin_op_compare_check(reg
, "==");
864 reg
[REG_R0
].type
= REG_S64
;
865 next_pc
+= sizeof(struct binary_op
);
870 ret
= bin_op_compare_check(reg
, "!=");
873 reg
[REG_R0
].type
= REG_S64
;
874 next_pc
+= sizeof(struct binary_op
);
879 ret
= bin_op_compare_check(reg
, ">");
882 reg
[REG_R0
].type
= REG_S64
;
883 next_pc
+= sizeof(struct binary_op
);
888 ret
= bin_op_compare_check(reg
, "<");
891 reg
[REG_R0
].type
= REG_S64
;
892 next_pc
+= sizeof(struct binary_op
);
897 ret
= bin_op_compare_check(reg
, ">=");
900 reg
[REG_R0
].type
= REG_S64
;
901 next_pc
+= sizeof(struct binary_op
);
906 ret
= bin_op_compare_check(reg
, "<=");
909 reg
[REG_R0
].type
= REG_S64
;
910 next_pc
+= sizeof(struct binary_op
);
915 case FILTER_OP_UNARY_PLUS
:
916 case FILTER_OP_UNARY_MINUS
:
917 case FILTER_OP_UNARY_NOT
:
919 struct unary_op
*insn
= (struct unary_op
*) pc
;
921 if (unlikely(insn
->reg
>= REG_ERROR
)) {
922 ERR("invalid register %u\n",
923 (unsigned int) insn
->reg
);
927 switch (reg
[insn
->reg
].type
) {
929 ERR("unknown register type\n");
934 ERR("Unary op can only be applied to numeric or floating point registers\n");
942 next_pc
+= sizeof(struct unary_op
);
946 case FILTER_OP_UNARY_PLUS_S64
:
947 case FILTER_OP_UNARY_MINUS_S64
:
948 case FILTER_OP_UNARY_NOT_S64
:
950 struct unary_op
*insn
= (struct unary_op
*) pc
;
952 if (unlikely(insn
->reg
>= REG_ERROR
)) {
953 ERR("invalid register %u\n",
954 (unsigned int) insn
->reg
);
958 if (reg
[insn
->reg
].type
!= REG_S64
) {
959 ERR("Invalid register type\n");
963 next_pc
+= sizeof(struct unary_op
);
967 case FILTER_OP_UNARY_PLUS_DOUBLE
:
968 case FILTER_OP_UNARY_MINUS_DOUBLE
:
969 case FILTER_OP_UNARY_NOT_DOUBLE
:
971 struct unary_op
*insn
= (struct unary_op
*) pc
;
973 if (unlikely(insn
->reg
>= REG_ERROR
)) {
974 ERR("invalid register %u\n",
975 (unsigned int) insn
->reg
);
979 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
980 ERR("Invalid register type\n");
984 next_pc
+= sizeof(struct unary_op
);
992 struct logical_op
*insn
= (struct logical_op
*) pc
;
994 if (unlikely(reg
[REG_R0
].type
== REG_TYPE_UNKNOWN
995 || reg
[REG_R0
].type
== REG_TYPE_UNKNOWN
996 || reg
[REG_R0
].type
== REG_STRING
997 || reg
[REG_R1
].type
== REG_STRING
)) {
998 ERR("Logical comparator can only be applied to numeric and floating point registers\n");
1003 dbg_printf("Validate jumping to bytecode offset %u\n",
1004 (unsigned int) insn
->skip_offset
);
1005 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
1006 ERR("Loops are not allowed in bytecode\n");
1010 next_pc
+= sizeof(struct logical_op
);
1015 case FILTER_OP_LOAD_FIELD_REF
:
1017 ERR("Unknown field ref type\n");
1021 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1022 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1024 struct load_op
*insn
= (struct load_op
*) pc
;
1025 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1027 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1028 ERR("invalid register %u\n",
1029 (unsigned int) insn
->reg
);
1033 dbg_printf("Validate load field ref offset %u type string\n",
1035 reg
[insn
->reg
].type
= REG_STRING
;
1036 reg
[insn
->reg
].literal
= 0;
1037 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1040 case FILTER_OP_LOAD_FIELD_REF_S64
:
1042 struct load_op
*insn
= (struct load_op
*) pc
;
1043 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1045 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1046 ERR("invalid register %u\n",
1047 (unsigned int) insn
->reg
);
1051 dbg_printf("Validate load field ref offset %u type s64\n",
1053 reg
[insn
->reg
].type
= REG_S64
;
1054 reg
[insn
->reg
].literal
= 0;
1055 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1058 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1060 struct load_op
*insn
= (struct load_op
*) pc
;
1061 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1063 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1064 ERR("invalid register %u\n",
1065 (unsigned int) insn
->reg
);
1069 dbg_printf("Validate load field ref offset %u type double\n",
1071 reg
[insn
->reg
].type
= REG_DOUBLE
;
1072 reg
[insn
->reg
].literal
= 0;
1073 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1077 case FILTER_OP_LOAD_STRING
:
1079 struct load_op
*insn
= (struct load_op
*) pc
;
1081 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1082 ERR("invalid register %u\n",
1083 (unsigned int) insn
->reg
);
1087 reg
[insn
->reg
].type
= REG_STRING
;
1088 reg
[insn
->reg
].literal
= 1;
1089 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1093 case FILTER_OP_LOAD_S64
:
1095 struct load_op
*insn
= (struct load_op
*) pc
;
1097 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1098 ERR("invalid register %u\n",
1099 (unsigned int) insn
->reg
);
1103 reg
[insn
->reg
].type
= REG_S64
;
1104 reg
[insn
->reg
].literal
= 1;
1105 next_pc
+= sizeof(struct load_op
)
1106 + sizeof(struct literal_numeric
);
1110 case FILTER_OP_LOAD_DOUBLE
:
1112 struct load_op
*insn
= (struct load_op
*) pc
;
1114 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1115 ERR("invalid register %u\n",
1116 (unsigned int) insn
->reg
);
1120 reg
[insn
->reg
].type
= REG_DOUBLE
;
1121 reg
[insn
->reg
].literal
= 1;
1122 next_pc
+= sizeof(struct load_op
)
1123 + sizeof(struct literal_double
);
1133 int lttng_filter_specialize_bytecode(struct bytecode_runtime
*bytecode
)
1135 void *pc
, *next_pc
, *start_pc
;
1137 struct vreg reg
[NR_REG
];
1140 for (i
= 0; i
< NR_REG
; i
++) {
1141 reg
[i
].type
= REG_TYPE_UNKNOWN
;
1145 start_pc
= &bytecode
->data
[0];
1146 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1148 switch (*(filter_opcode_t
*) pc
) {
1149 case FILTER_OP_UNKNOWN
:
1151 ERR("unknown bytecode op %u\n",
1152 (unsigned int) *(filter_opcode_t
*) pc
);
1156 case FILTER_OP_RETURN
:
1164 case FILTER_OP_PLUS
:
1165 case FILTER_OP_MINUS
:
1166 case FILTER_OP_RSHIFT
:
1167 case FILTER_OP_LSHIFT
:
1168 case FILTER_OP_BIN_AND
:
1169 case FILTER_OP_BIN_OR
:
1170 case FILTER_OP_BIN_XOR
:
1171 ERR("unsupported bytecode op %u\n",
1172 (unsigned int) *(filter_opcode_t
*) pc
);
1183 reg
[REG_R0
].type
= REG_S64
;
1184 next_pc
+= sizeof(struct binary_op
);
1189 case FILTER_OP_UNARY_PLUS
:
1191 struct unary_op
*insn
= (struct unary_op
*) pc
;
1193 switch(reg
[insn
->reg
].type
) {
1195 ERR("unknown register type\n");
1200 insn
->op
= FILTER_OP_UNARY_PLUS_S64
;
1203 insn
->op
= FILTER_OP_UNARY_PLUS_DOUBLE
;
1209 case FILTER_OP_UNARY_MINUS
:
1211 struct unary_op
*insn
= (struct unary_op
*) pc
;
1213 switch(reg
[insn
->reg
].type
) {
1215 ERR("unknown register type\n");
1220 insn
->op
= FILTER_OP_UNARY_MINUS_S64
;
1223 insn
->op
= FILTER_OP_UNARY_MINUS_DOUBLE
;
1229 case FILTER_OP_UNARY_NOT
:
1231 struct unary_op
*insn
= (struct unary_op
*) pc
;
1233 switch(reg
[insn
->reg
].type
) {
1235 ERR("unknown register type\n");
1240 insn
->op
= FILTER_OP_UNARY_NOT_S64
;
1243 insn
->op
= FILTER_OP_UNARY_NOT_DOUBLE
;
1249 case FILTER_OP_UNARY_PLUS_S64
:
1250 case FILTER_OP_UNARY_MINUS_S64
:
1251 case FILTER_OP_UNARY_NOT_S64
:
1252 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1253 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1254 case FILTER_OP_UNARY_NOT_DOUBLE
:
1256 next_pc
+= sizeof(struct unary_op
);
1264 next_pc
+= sizeof(struct logical_op
);
1269 case FILTER_OP_LOAD_FIELD_REF
:
1271 ERR("Unknown field ref type\n");
1275 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1276 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1278 struct load_op
*insn
= (struct load_op
*) pc
;
1280 reg
[insn
->reg
].type
= REG_STRING
;
1281 reg
[insn
->reg
].literal
= 0;
1282 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1285 case FILTER_OP_LOAD_FIELD_REF_S64
:
1287 struct load_op
*insn
= (struct load_op
*) pc
;
1289 reg
[insn
->reg
].type
= REG_S64
;
1290 reg
[insn
->reg
].literal
= 0;
1291 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1294 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1296 struct load_op
*insn
= (struct load_op
*) pc
;
1298 reg
[insn
->reg
].type
= REG_DOUBLE
;
1299 reg
[insn
->reg
].literal
= 0;
1300 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1304 case FILTER_OP_LOAD_STRING
:
1306 struct load_op
*insn
= (struct load_op
*) pc
;
1308 reg
[insn
->reg
].type
= REG_STRING
;
1309 reg
[insn
->reg
].literal
= 1;
1310 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1314 case FILTER_OP_LOAD_S64
:
1316 struct load_op
*insn
= (struct load_op
*) pc
;
1318 reg
[insn
->reg
].type
= REG_S64
;
1319 reg
[insn
->reg
].literal
= 1;
1320 next_pc
+= sizeof(struct load_op
)
1321 + sizeof(struct literal_numeric
);
1325 case FILTER_OP_LOAD_DOUBLE
:
1327 struct load_op
*insn
= (struct load_op
*) pc
;
1329 reg
[insn
->reg
].type
= REG_DOUBLE
;
1330 reg
[insn
->reg
].literal
= 1;
1331 next_pc
+= sizeof(struct load_op
)
1332 + sizeof(struct literal_double
);
1344 int apply_field_reloc(struct ltt_event
*event
,
1345 struct bytecode_runtime
*runtime
,
1346 uint32_t runtime_len
,
1347 uint32_t reloc_offset
,
1348 const char *field_name
)
1350 const struct lttng_event_desc
*desc
;
1351 const struct lttng_event_field
*fields
, *field
= NULL
;
1352 unsigned int nr_fields
, i
;
1353 struct field_ref
*field_ref
;
1355 uint32_t field_offset
= 0;
1357 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1359 /* Ensure that the reloc is within the code */
1360 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1363 /* Lookup event by name */
1367 fields
= desc
->fields
;
1370 nr_fields
= desc
->nr_fields
;
1371 for (i
= 0; i
< nr_fields
; i
++) {
1372 if (!strcmp(fields
[i
].name
, field_name
)) {
1376 /* compute field offset */
1377 switch (fields
[i
].type
.atype
) {
1380 field_offset
+= sizeof(int64_t);
1383 case atype_sequence
:
1384 field_offset
+= sizeof(unsigned long);
1385 field_offset
+= sizeof(void *);
1388 field_offset
+= sizeof(void *);
1391 field_offset
+= sizeof(double);
1400 /* Check if field offset is too large for 16-bit offset */
1401 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1405 op
= (struct load_op
*) &runtime
->data
[reloc_offset
];
1406 field_ref
= (struct field_ref
*) op
->data
;
1407 switch (field
->type
.atype
) {
1410 op
->op
= FILTER_OP_LOAD_FIELD_REF_S64
;
1413 case atype_sequence
:
1414 op
->op
= FILTER_OP_LOAD_FIELD_REF_SEQUENCE
;
1417 op
->op
= FILTER_OP_LOAD_FIELD_REF_STRING
;
1420 op
->op
= FILTER_OP_LOAD_FIELD_REF_DOUBLE
;
1426 field_ref
->offset
= (uint16_t) field_offset
;
1431 * Take a bytecode with reloc table and link it to an event to create a
1435 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1436 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1438 int ret
, offset
, next_offset
;
1439 struct bytecode_runtime
*runtime
= NULL
;
1440 size_t runtime_alloc_len
;
1442 if (!filter_bytecode
)
1444 /* Even is not connected to any description */
1447 /* Bytecode already linked */
1448 if (event
->filter
|| event
->filter_data
)
1451 dbg_printf("Linking\n");
1453 /* We don't need the reloc table in the runtime */
1454 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
1455 runtime
= zmalloc(runtime_alloc_len
);
1460 runtime
->len
= filter_bytecode
->reloc_offset
;
1461 /* copy original bytecode */
1462 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
1464 * apply relocs. Those are a uint16_t (offset in bytecode)
1465 * followed by a string (field name).
1467 for (offset
= filter_bytecode
->reloc_offset
;
1468 offset
< filter_bytecode
->len
;
1469 offset
= next_offset
) {
1470 uint16_t reloc_offset
=
1471 *(uint16_t *) &filter_bytecode
->data
[offset
];
1472 const char *field_name
=
1473 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
1475 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1479 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1481 /* Validate bytecode */
1482 ret
= lttng_filter_validate_bytecode(runtime
);
1486 /* Specialize bytecode */
1487 ret
= lttng_filter_specialize_bytecode(runtime
);
1491 event
->filter_data
= runtime
;
1492 event
->filter
= lttng_filter_interpret_bytecode
;
1496 event
->filter
= lttng_filter_false
;
1501 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1502 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1506 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1508 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1513 * Link bytecode to all events for a wildcard. Skips events that already
1514 * have a bytecode linked.
1515 * We do not set each event's filter_bytecode field, because they do not
1516 * own the filter_bytecode: the wildcard owns it.
1518 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1520 struct ltt_event
*event
;
1523 if (!wildcard
->filter_bytecode
)
1526 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1529 ret
= _lttng_filter_event_link_bytecode(event
,
1530 wildcard
->filter_bytecode
);
1532 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1540 * Need to attach filter to an event before starting tracing for the
1541 * session. We own the filter_bytecode if we return success.
1543 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1544 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1546 if (event
->chan
->session
->been_active
)
1548 if (event
->filter_bytecode
)
1550 event
->filter_bytecode
= filter_bytecode
;
1555 * Need to attach filter to a wildcard before starting tracing for the
1556 * session. We own the filter_bytecode if we return success.
1558 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1559 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1561 if (wildcard
->chan
->session
->been_active
)
1563 if (wildcard
->filter_bytecode
)
1565 wildcard
->filter_bytecode
= filter_bytecode
;