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"
37 #define min_t(type, a, b) \
38 ((type) (a) < (type) (b) ? (type) (a) : (type) (b))
42 #define likely(x) __builtin_expect(!!(x), 1)
46 #define unlikely(x) __builtin_expect(!!(x), 0)
50 #define dbg_printf(fmt, args...) printf("[debug bytecode] " fmt, ## args)
52 #define dbg_printf(fmt, args...) \
54 /* do nothing but check printf format */ \
56 printf("[debug bytecode] " fmt, ## args); \
61 struct bytecode_runtime
{
69 REG_STRING
, /* NULL-terminated string */
70 REG_SEQUENCE
, /* non-null terminated */
76 int literal
; /* is string literal ? */
79 static const char *opnames
[] = {
80 [ FILTER_OP_UNKNOWN
] = "UNKNOWN",
82 [ FILTER_OP_RETURN
] = "RETURN",
85 [ FILTER_OP_MUL
] = "MUL",
86 [ FILTER_OP_DIV
] = "DIV",
87 [ FILTER_OP_MOD
] = "MOD",
88 [ FILTER_OP_PLUS
] = "PLUS",
89 [ FILTER_OP_MINUS
] = "MINUS",
90 [ FILTER_OP_RSHIFT
] = "RSHIFT",
91 [ FILTER_OP_LSHIFT
] = "LSHIFT",
92 [ FILTER_OP_BIN_AND
] = "BIN_AND",
93 [ FILTER_OP_BIN_OR
] = "BIN_OR",
94 [ FILTER_OP_BIN_XOR
] = "BIN_XOR",
95 [ FILTER_OP_EQ
] = "EQ",
96 [ FILTER_OP_NE
] = "NE",
97 [ FILTER_OP_GT
] = "GT",
98 [ FILTER_OP_LT
] = "LT",
99 [ FILTER_OP_GE
] = "GE",
100 [ FILTER_OP_LE
] = "LE",
103 [ FILTER_OP_UNARY_PLUS
] = "UNARY_PLUS",
104 [ FILTER_OP_UNARY_MINUS
] = "UNARY_MINUS",
105 [ FILTER_OP_UNARY_NOT
] = "UNARY_NOT",
108 [ FILTER_OP_AND
] = "AND",
109 [ FILTER_OP_OR
] = "OR",
112 [ FILTER_OP_LOAD_FIELD_REF
] = "LOAD_FIELD_REF",
113 [ FILTER_OP_LOAD_STRING
] = "LOAD_STRING",
114 [ FILTER_OP_LOAD_S64
] = "LOAD_S64",
118 const char *print_op(enum filter_op op
)
120 if (op
>= NR_FILTER_OPS
)
127 * -1: wildcard found.
128 * -2: unknown escape char.
133 int parse_char(const char **p
)
153 int reg_strcmp(struct reg reg
[NR_REG
], const char *cmp_type
)
155 const char *p
= reg
[REG_R0
].str
, *q
= reg
[REG_R1
].str
;
162 if (unlikely(p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')) {
163 if (q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')
169 if (unlikely(q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')) {
170 if (p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')
176 if (reg
[REG_R0
].literal
) {
177 ret
= parse_char(&p
);
180 } else if (ret
== -2) {
183 /* else compare both char */
185 if (reg
[REG_R1
].literal
) {
186 ret
= parse_char(&q
);
189 } else if (ret
== -2) {
210 int lttng_filter_false(void *filter_data
,
211 const char *filter_stack_data
)
217 int lttng_filter_interpret_bytecode(void *filter_data
,
218 const char *filter_stack_data
)
220 struct bytecode_runtime
*bytecode
= filter_data
;
221 void *pc
, *next_pc
, *start_pc
;
224 struct reg reg
[NR_REG
];
227 for (i
= 0; i
< NR_REG
; i
++) {
228 reg
[i
].type
= REG_S64
;
235 start_pc
= &bytecode
->data
[0];
236 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
238 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
239 fprintf(stderr
, "[error] filter bytecode overflow\n");
243 dbg_printf("Executing op %s (%u)\n",
244 print_op((unsigned int) *(filter_opcode_t
*) pc
),
245 (unsigned int) *(filter_opcode_t
*) pc
);
246 switch (*(filter_opcode_t
*) pc
) {
247 case FILTER_OP_UNKNOWN
:
249 fprintf(stderr
, "[error] unknown bytecode op %u\n",
250 (unsigned int) *(filter_opcode_t
*) pc
);
254 case FILTER_OP_RETURN
:
264 case FILTER_OP_MINUS
:
265 case FILTER_OP_RSHIFT
:
266 case FILTER_OP_LSHIFT
:
267 case FILTER_OP_BIN_AND
:
268 case FILTER_OP_BIN_OR
:
269 case FILTER_OP_BIN_XOR
:
270 fprintf(stderr
, "[error] unsupported bytecode op %u\n",
271 (unsigned int) *(filter_opcode_t
*) pc
);
277 if (unlikely((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R1
].type
!= REG_S64
)
278 || (reg
[REG_R0
].type
!= REG_S64
&& reg
[REG_R1
].type
== REG_S64
))) {
279 fprintf(stderr
, "[error] type mismatch for '==' binary operator\n");
283 switch (reg
[REG_R0
].type
) {
285 fprintf(stderr
, "[error] unknown register type\n");
291 reg
[REG_R0
].v
= (reg_strcmp(reg
, "==") == 0);
294 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].v
);
297 reg
[REG_R0
].type
= REG_S64
;
298 next_pc
+= sizeof(struct binary_op
);
303 if (unlikely((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R1
].type
!= REG_S64
)
304 || (reg
[REG_R0
].type
!= REG_S64
&& reg
[REG_R1
].type
== REG_S64
))) {
305 fprintf(stderr
, "[error] type mismatch for '!=' binary operator\n");
309 switch (reg
[REG_R0
].type
) {
311 fprintf(stderr
, "[error] unknown register type\n");
317 reg
[REG_R0
].v
= (reg_strcmp(reg
, "!=") != 0);
320 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].v
);
323 reg
[REG_R0
].type
= REG_S64
;
324 next_pc
+= sizeof(struct binary_op
);
329 if (unlikely((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R1
].type
!= REG_S64
)
330 || (reg
[REG_R0
].type
!= REG_S64
&& reg
[REG_R1
].type
== REG_S64
))) {
331 fprintf(stderr
, "[error] type mismatch for '>' binary operator\n");
335 switch (reg
[REG_R0
].type
) {
337 fprintf(stderr
, "[error] unknown register type\n");
343 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">") > 0);
346 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].v
);
349 reg
[REG_R0
].type
= REG_S64
;
350 next_pc
+= sizeof(struct binary_op
);
355 if (unlikely((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R1
].type
!= REG_S64
)
356 || (reg
[REG_R0
].type
!= REG_S64
&& reg
[REG_R1
].type
== REG_S64
))) {
357 fprintf(stderr
, "[error] type mismatch for '<' binary operator\n");
361 switch (reg
[REG_R0
].type
) {
363 fprintf(stderr
, "[error] unknown register type\n");
369 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<") < 0);
372 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].v
);
375 reg
[REG_R0
].type
= REG_S64
;
376 next_pc
+= sizeof(struct binary_op
);
381 if (unlikely((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R1
].type
!= REG_S64
)
382 || (reg
[REG_R0
].type
!= REG_S64
&& reg
[REG_R1
].type
== REG_S64
))) {
383 fprintf(stderr
, "[error] type mismatch for '>=' binary operator\n");
387 switch (reg
[REG_R0
].type
) {
389 fprintf(stderr
, "[error] unknown register type\n");
395 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">=") >= 0);
398 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].v
);
401 reg
[REG_R0
].type
= REG_S64
;
402 next_pc
+= sizeof(struct binary_op
);
407 if (unlikely((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R1
].type
!= REG_S64
)
408 || (reg
[REG_R0
].type
!= REG_S64
&& reg
[REG_R1
].type
== REG_S64
))) {
409 fprintf(stderr
, "[error] type mismatch for '<=' binary operator\n");
413 switch (reg
[REG_R0
].type
) {
415 fprintf(stderr
, "[error] unknown register type\n");
421 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<=") <= 0);
424 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].v
);
427 reg
[REG_R0
].type
= REG_S64
;
428 next_pc
+= sizeof(struct binary_op
);
433 case FILTER_OP_UNARY_PLUS
:
435 struct unary_op
*insn
= (struct unary_op
*) pc
;
437 if (unlikely(insn
->reg
>= REG_ERROR
)) {
438 fprintf(stderr
, "[error] invalid register %u\n",
439 (unsigned int) insn
->reg
);
443 if (unlikely(reg
[insn
->reg
].type
!= REG_S64
)) {
444 fprintf(stderr
, "[error] Unary plus can only be applied to numeric register\n");
448 next_pc
+= sizeof(struct unary_op
);
451 case FILTER_OP_UNARY_MINUS
:
453 struct unary_op
*insn
= (struct unary_op
*) pc
;
455 if (unlikely(insn
->reg
>= REG_ERROR
)) {
456 fprintf(stderr
, "[error] invalid register %u\n",
457 (unsigned int) insn
->reg
);
461 if (unlikely(reg
[insn
->reg
].type
!= REG_S64
)) {
462 fprintf(stderr
, "[error] Unary minus can only be applied to numeric register\n");
466 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
467 next_pc
+= sizeof(struct unary_op
);
470 case FILTER_OP_UNARY_NOT
:
472 struct unary_op
*insn
= (struct unary_op
*) pc
;
474 if (unlikely(insn
->reg
>= REG_ERROR
)) {
475 fprintf(stderr
, "[error] invalid register %u\n",
476 (unsigned int) insn
->reg
);
480 if (unlikely(reg
[insn
->reg
].type
!= REG_S64
)) {
481 fprintf(stderr
, "[error] Unary not can only be applied to numeric register\n");
485 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
486 next_pc
+= sizeof(struct unary_op
);
492 struct logical_op
*insn
= (struct logical_op
*) pc
;
494 if (unlikely(reg
[REG_R0
].type
!= REG_S64
)) {
495 fprintf(stderr
, "[error] Logical operator 'and' can only be applied to numeric register\n");
500 /* If REG_R0 is 0, skip and evaluate to 0 */
501 if (reg
[REG_R0
].v
== 0) {
502 dbg_printf("Jumping to bytecode offset %u\n",
503 (unsigned int) insn
->skip_offset
);
504 next_pc
= start_pc
+ insn
->skip_offset
;
505 if (unlikely(next_pc
<= pc
)) {
506 fprintf(stderr
, "[error] Loops are not allowed in bytecode\n");
511 next_pc
+= sizeof(struct logical_op
);
517 struct logical_op
*insn
= (struct logical_op
*) pc
;
519 if (unlikely(reg
[REG_R0
].type
!= REG_S64
)) {
520 fprintf(stderr
, "[error] Logical operator 'and' can only be applied to numeric register\n");
525 /* If REG_R0 is nonzero, skip and evaluate to 1 */
526 if (reg
[REG_R0
].v
!= 0) {
528 dbg_printf("Jumping to bytecode offset %u\n",
529 (unsigned int) insn
->skip_offset
);
530 next_pc
= start_pc
+ insn
->skip_offset
;
531 if (unlikely(next_pc
<= pc
)) {
532 fprintf(stderr
, "[error] Loops are not allowed in bytecode\n");
537 next_pc
+= sizeof(struct logical_op
);
543 case FILTER_OP_LOAD_FIELD_REF
:
545 struct load_op
*insn
= (struct load_op
*) pc
;
546 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
548 if (unlikely(insn
->reg
>= REG_ERROR
)) {
549 fprintf(stderr
, "[error] invalid register %u\n",
550 (unsigned int) insn
->reg
);
554 dbg_printf("load field ref offset %u type %u\n",
555 ref
->offset
, ref
->type
);
557 case FIELD_REF_UNKNOWN
:
559 fprintf(stderr
, "[error] unknown field ref type\n");
563 case FIELD_REF_STRING
:
565 *(const char * const *) &filter_stack_data
[ref
->offset
];
566 reg
[insn
->reg
].type
= REG_STRING
;
567 reg
[insn
->reg
].seq_len
= UINT_MAX
;
568 reg
[insn
->reg
].literal
= 0;
569 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
571 case FIELD_REF_SEQUENCE
:
572 reg
[insn
->reg
].seq_len
=
573 *(unsigned long *) &filter_stack_data
[ref
->offset
];
575 *(const char **) (&filter_stack_data
[ref
->offset
576 + sizeof(unsigned long)]);
577 reg
[insn
->reg
].type
= REG_SEQUENCE
;
578 reg
[insn
->reg
].literal
= 0;
581 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
582 sizeof(struct literal_numeric
));
583 reg
[insn
->reg
].type
= REG_S64
;
584 reg
[insn
->reg
].literal
= 0;
585 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
589 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
593 case FILTER_OP_LOAD_STRING
:
595 struct load_op
*insn
= (struct load_op
*) pc
;
597 if (unlikely(insn
->reg
>= REG_ERROR
)) {
598 fprintf(stderr
, "[error] invalid register %u\n",
599 (unsigned int) insn
->reg
);
603 dbg_printf("load string %s\n", insn
->data
);
604 reg
[insn
->reg
].str
= insn
->data
;
605 reg
[insn
->reg
].type
= REG_STRING
;
606 reg
[insn
->reg
].seq_len
= UINT_MAX
;
607 reg
[insn
->reg
].literal
= 1;
608 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
612 case FILTER_OP_LOAD_S64
:
614 struct load_op
*insn
= (struct load_op
*) pc
;
616 if (unlikely(insn
->reg
>= REG_ERROR
)) {
617 fprintf(stderr
, "[error] invalid register %u\n",
618 (unsigned int) insn
->reg
);
622 memcpy(®
[insn
->reg
].v
, insn
->data
,
623 sizeof(struct literal_numeric
));
624 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
625 reg
[insn
->reg
].type
= REG_S64
;
626 next_pc
+= sizeof(struct load_op
)
627 + sizeof(struct literal_numeric
);
633 /* return 0 (discard) on error */
640 int apply_field_reloc(struct ltt_event
*event
,
641 struct bytecode_runtime
*runtime
,
642 uint32_t runtime_len
,
643 uint32_t reloc_offset
,
644 const char *field_name
)
646 const struct lttng_event_desc
*desc
;
647 const struct lttng_event_field
*fields
, *field
= NULL
;
648 unsigned int nr_fields
, i
;
649 struct field_ref
*field_ref
;
650 uint32_t field_offset
= 0;
652 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
654 /* Ensure that the reloc is within the code */
655 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
658 /* Lookup event by name */
662 fields
= desc
->fields
;
665 nr_fields
= desc
->nr_fields
;
666 for (i
= 0; i
< nr_fields
; i
++) {
667 if (!strcmp(fields
[i
].name
, field_name
)) {
671 /* compute field offset */
672 switch (fields
[i
].type
.atype
) {
675 field_offset
+= sizeof(int64_t);
679 field_offset
+= sizeof(unsigned long);
680 field_offset
+= sizeof(void *);
683 field_offset
+= sizeof(void *);
686 field_offset
+= sizeof(double);
694 /* Check if field offset is too large for 16-bit offset */
695 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
699 field_ref
= (struct field_ref
*) &runtime
->data
[reloc_offset
];
700 switch (field
->type
.atype
) {
703 field_ref
->type
= FIELD_REF_S64
;
704 field_ref
->type
= FIELD_REF_S64
;
708 field_ref
->type
= FIELD_REF_SEQUENCE
;
711 field_ref
->type
= FIELD_REF_STRING
;
719 field_ref
->offset
= (uint16_t) field_offset
;
724 * Take a bytecode with reloc table and link it to an event to create a
728 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
729 struct lttng_ust_filter_bytecode
*filter_bytecode
)
731 int ret
, offset
, next_offset
;
732 struct bytecode_runtime
*runtime
= NULL
;
733 size_t runtime_alloc_len
;
735 if (!filter_bytecode
)
737 /* Even is not connected to any description */
740 /* Bytecode already linked */
741 if (event
->filter
|| event
->filter_data
)
744 dbg_printf("Linking\n");
746 /* We don't need the reloc table in the runtime */
747 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
748 runtime
= zmalloc(runtime_alloc_len
);
753 runtime
->len
= filter_bytecode
->reloc_offset
;
754 /* copy original bytecode */
755 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
757 * apply relocs. Those are a uint16_t (offset in bytecode)
758 * followed by a string (field name).
760 for (offset
= filter_bytecode
->reloc_offset
;
761 offset
< filter_bytecode
->len
;
762 offset
= next_offset
) {
763 uint16_t reloc_offset
=
764 *(uint16_t *) &filter_bytecode
->data
[offset
];
765 const char *field_name
=
766 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
768 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
772 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
774 event
->filter_data
= runtime
;
775 event
->filter
= lttng_filter_interpret_bytecode
;
779 event
->filter
= lttng_filter_false
;
784 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
785 struct lttng_ust_filter_bytecode
*filter_bytecode
)
789 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
791 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
796 * Link bytecode to all events for a wildcard. Skips events that already
797 * have a bytecode linked.
798 * We do not set each event's filter_bytecode field, because they do not
799 * own the filter_bytecode: the wildcard owns it.
801 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
803 struct ltt_event
*event
;
806 if (!wildcard
->filter_bytecode
)
809 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
812 ret
= _lttng_filter_event_link_bytecode(event
,
813 wildcard
->filter_bytecode
);
815 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
823 * Need to attach filter to an event before starting tracing for the
824 * session. We own the filter_bytecode if we return success.
826 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
827 struct lttng_ust_filter_bytecode
*filter_bytecode
)
829 if (event
->chan
->session
->been_active
)
831 if (event
->filter_bytecode
)
833 event
->filter_bytecode
= filter_bytecode
;
838 * Need to attach filter to a wildcard before starting tracing for the
839 * session. We own the filter_bytecode if we return success.
841 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
842 struct lttng_ust_filter_bytecode
*filter_bytecode
)
844 if (wildcard
->chan
->session
->been_active
)
846 if (wildcard
->filter_bytecode
)
848 wildcard
->filter_bytecode
= filter_bytecode
;