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",
108 /* binary comparators */
109 [ FILTER_OP_EQ
] = "EQ",
110 [ FILTER_OP_NE
] = "NE",
111 [ FILTER_OP_GT
] = "GT",
112 [ FILTER_OP_LT
] = "LT",
113 [ FILTER_OP_GE
] = "GE",
114 [ FILTER_OP_LE
] = "LE",
116 /* string binary comparators */
117 [ FILTER_OP_EQ_STRING
] = "EQ_STRING",
118 [ FILTER_OP_NE_STRING
] = "NE_STRING",
119 [ FILTER_OP_GT_STRING
] = "GT_STRING",
120 [ FILTER_OP_LT_STRING
] = "LT_STRING",
121 [ FILTER_OP_GE_STRING
] = "GE_STRING",
122 [ FILTER_OP_LE_STRING
] = "LE_STRING",
124 /* s64 binary comparators */
125 [ FILTER_OP_EQ_S64
] = "EQ_S64",
126 [ FILTER_OP_NE_S64
] = "NE_S64",
127 [ FILTER_OP_GT_S64
] = "GT_S64",
128 [ FILTER_OP_LT_S64
] = "LT_S64",
129 [ FILTER_OP_GE_S64
] = "GE_S64",
130 [ FILTER_OP_LE_S64
] = "LE_S64",
132 /* double binary comparators */
133 [ FILTER_OP_EQ_DOUBLE
] = "EQ_DOUBLE",
134 [ FILTER_OP_NE_DOUBLE
] = "NE_DOUBLE",
135 [ FILTER_OP_GT_DOUBLE
] = "GT_DOUBLE",
136 [ FILTER_OP_LT_DOUBLE
] = "LT_DOUBLE",
137 [ FILTER_OP_GE_DOUBLE
] = "GE_DOUBLE",
138 [ FILTER_OP_LE_DOUBLE
] = "LE_DOUBLE",
142 [ FILTER_OP_UNARY_PLUS
] = "UNARY_PLUS",
143 [ FILTER_OP_UNARY_MINUS
] = "UNARY_MINUS",
144 [ FILTER_OP_UNARY_NOT
] = "UNARY_NOT",
145 [ FILTER_OP_UNARY_PLUS_S64
] = "UNARY_PLUS_S64",
146 [ FILTER_OP_UNARY_MINUS_S64
] = "UNARY_MINUS_S64",
147 [ FILTER_OP_UNARY_NOT_S64
] = "UNARY_NOT_S64",
148 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = "UNARY_PLUS_DOUBLE",
149 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = "UNARY_MINUS_DOUBLE",
150 [ FILTER_OP_UNARY_NOT_DOUBLE
] = "UNARY_NOT_DOUBLE",
153 [ FILTER_OP_AND
] = "AND",
154 [ FILTER_OP_OR
] = "OR",
157 [ FILTER_OP_LOAD_FIELD_REF
] = "LOAD_FIELD_REF",
158 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = "LOAD_FIELD_REF_STRING",
159 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = "LOAD_FIELD_REF_SEQUENCE",
160 [ FILTER_OP_LOAD_FIELD_REF_S64
] = "LOAD_FIELD_REF_S64",
161 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = "LOAD_FIELD_REF_DOUBLE",
163 [ FILTER_OP_LOAD_STRING
] = "LOAD_STRING",
164 [ FILTER_OP_LOAD_S64
] = "LOAD_S64",
165 [ FILTER_OP_LOAD_DOUBLE
] = "LOAD_DOUBLE",
169 const char *print_op(enum filter_op op
)
171 if (op
>= NR_FILTER_OPS
)
178 * -1: wildcard found.
179 * -2: unknown escape char.
184 int parse_char(const char **p
)
204 int reg_strcmp(struct reg reg
[NR_REG
], const char *cmp_type
)
206 const char *p
= reg
[REG_R0
].str
, *q
= reg
[REG_R1
].str
;
213 if (unlikely(p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')) {
214 if (q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')
220 if (unlikely(q
- reg
[REG_R1
].str
> reg
[REG_R1
].seq_len
|| *q
== '\0')) {
221 if (p
- reg
[REG_R0
].str
> reg
[REG_R0
].seq_len
|| *p
== '\0')
227 if (reg
[REG_R0
].literal
) {
228 ret
= parse_char(&p
);
231 } else if (ret
== -2) {
234 /* else compare both char */
236 if (reg
[REG_R1
].literal
) {
237 ret
= parse_char(&q
);
240 } else if (ret
== -2) {
261 int lttng_filter_false(void *filter_data
,
262 const char *filter_stack_data
)
267 #define INTERPRETER_USE_SWITCH
269 #ifdef INTERPRETER_USE_SWITCH
272 start_pc = &bytecode->data[0]; \
273 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
275 dbg_printf("Executing op %s (%u)\n", \
276 print_op((unsigned int) *(filter_opcode_t *) pc), \
277 (unsigned int) *(filter_opcode_t *) pc); \
278 switch (*(filter_opcode_t *) pc) {
280 #define OP(name) case name
294 int lttng_filter_interpret_bytecode(void *filter_data
,
295 const char *filter_stack_data
)
297 struct bytecode_runtime
*bytecode
= filter_data
;
298 void *pc
, *next_pc
, *start_pc
;
301 struct reg reg
[NR_REG
];
302 #ifndef INTERPRETER_USE_SWITCH
303 static void *dispatch
[NR_FILTER_OPS
] = {
304 [ FILTER_OP_UNKNOWN
] = &&LABEL_FILTER_OP_UNKNOWN
= 0,
306 [ FILTER_OP_RETURN
] = &&LABEL_FILTER_OP_RETURN
,
309 [ FILTER_OP_MUL
] = &&LABEL_FILTER_OP_MUL
,
310 [ FILTER_OP_DIV
] = &&LABEL_FILTER_OP_DIV
,
311 [ FILTER_OP_MOD
] = &&LABEL_FILTER_OP_MOD
,
312 [ FILTER_OP_PLUS
] = &&LABEL_FILTER_OP_PLUS
,
313 [ FILTER_OP_MINUS
] = &&LABEL_FILTER_OP_MINUS
,
314 [ FILTER_OP_RSHIFT
] = &&LABEL_FILTER_OP_RSHIFT
,
315 [ FILTER_OP_LSHIFT
] = &&LABEL_FILTER_OP_LSHIFT
,
316 [ FILTER_OP_BIN_AND
] = &&LABEL_FILTER_OP_BIN_AND
,
317 [ FILTER_OP_BIN_OR
] = &&LABEL_FILTER_OP_BIN_OR
,
318 [ FILTER_OP_BIN_XOR
] = &&LABEL_FILTER_OP_BIN_XOR
,
320 /* binary comparators */
321 [ FILTER_OP_EQ
] = &&LABEL_FILTER_OP_EQ
,
322 [ FILTER_OP_NE
] = &&LABEL_FILTER_OP_NE
,
323 [ FILTER_OP_GT
] = &&LABEL_FILTER_OP_GT
,
324 [ FILTER_OP_LT
] = &&LABEL_FILTER_OP_LT
,
325 [ FILTER_OP_GE
] = &&LABEL_FILTER_OP_GE
,
326 [ FILTER_OP_LE
] = &&LABEL_FILTER_OP_LE
,
328 /* string binary comparator */
329 [ FILTER_OP_EQ_STRING
] = &&LABEL_FILTER_OP_EQ_STRING
,
330 [ FILTER_OP_NE_STRING
] = &&LABEL_FILTER_OP_NE_STRING
,
331 [ FILTER_OP_GT_STRING
] = &&LABEL_FILTER_OP_GT_STRING
,
332 [ FILTER_OP_LT_STRING
] = &&LABEL_FILTER_OP_LT_STRING
,
333 [ FILTER_OP_GE_STRING
] = &&LABEL_FILTER_OP_GE_STRING
,
334 [ FILTER_OP_LE_STRING
] = &&LABEL_FILTER_OP_LE_STRING
,
336 /* s64 binary comparator */
337 [ FILTER_OP_EQ_S64
] = &&LABEL_FILTER_OP_EQ_S64
,
338 [ FILTER_OP_NE_S64
] = &&LABEL_FILTER_OP_NE_S64
,
339 [ FILTER_OP_GT_S64
] = &&LABEL_FILTER_OP_GT_S64
,
340 [ FILTER_OP_LT_S64
] = &&LABEL_FILTER_OP_LT_S64
,
341 [ FILTER_OP_GE_S64
] = &&LABEL_FILTER_OP_GE_S64
,
342 [ FILTER_OP_LE_S64
] = &&LABEL_FILTER_OP_LE_S64
,
344 /* double binary comparator */
345 [ FILTER_OP_EQ_DOUBLE
] = &&LABEL_FILTER_OP_EQ_DOUBLE
,
346 [ FILTER_OP_NE_DOUBLE
] = &&LABEL_FILTER_OP_NE_DOUBLE
,
347 [ FILTER_OP_GT_DOUBLE
] = &&LABEL_FILTER_OP_GT_DOUBLE
,
348 [ FILTER_OP_LT_DOUBLE
] = &&LABEL_FILTER_OP_LT_DOUBLE
,
349 [ FILTER_OP_GE_DOUBLE
] = &&LABEL_FILTER_OP_GE_DOUBLE
,
350 [ FILTER_OP_LE_DOUBLE
] = &&LABEL_FILTER_OP_LE_DOUBLE
,
353 [ FILTER_OP_UNARY_PLUS
] = &&LABEL_FILTER_OP_UNARY_PLUS
,
354 [ FILTER_OP_UNARY_MINUS
] = &&LABEL_FILTER_OP_UNARY_MINUS
,
355 [ FILTER_OP_UNARY_NOT
] = &&LABEL_FILTER_OP_UNARY_NOT
,
356 [ FILTER_OP_UNARY_PLUS_S64
] = &&LABEL_FILTER_OP_UNARY_PLUS_S64
,
357 [ FILTER_OP_UNARY_MINUS_S64
] = &&LABEL_FILTER_OP_UNARY_MINUS_S64
,
358 [ FILTER_OP_UNARY_NOT_S64
] = &&LABEL_FILTER_OP_UNARY_NOT_S64
,
359 [ FILTER_OP_UNARY_PLUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE
,
360 [ FILTER_OP_UNARY_MINUS_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE
,
361 [ FILTER_OP_UNARY_NOT_DOUBLE
] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE
,
364 [ FILTER_OP_AND
] = &&LABEL_FILTER_OP_AND
,
365 [ FILTER_OP_OR
] = &&LABEL_FILTER_OP_OR
,
368 [ FILTER_OP_LOAD_FIELD_REF
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF
,
369 [ FILTER_OP_LOAD_FIELD_REF_STRING
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING
,
370 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE
,
371 [ FILTER_OP_LOAD_FIELD_REF_S64
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64
,
372 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE
,
374 [ FILTER_OP_LOAD_STRING
] = &&LABEL_FILTER_OP_LOAD_STRING
,
375 [ FILTER_OP_LOAD_S64
] = &&LABEL_FILTER_OP_LOAD_S64
,
376 [ FILTER_OP_LOAD_DOUBLE
] = &&LABEL_FILTER_OP_LOAD_DOUBLE
,
378 #endif /* #ifndef INTERPRETER_USE_SWITCH */
382 OP(FILTER_OP_UNKNOWN
):
383 OP(FILTER_OP_LOAD_FIELD_REF
):
384 #ifdef INTERPRETER_USE_SWITCH
386 #endif /* INTERPRETER_USE_SWITCH */
387 ERR("unknown bytecode op %u\n",
388 (unsigned int) *(filter_opcode_t
*) pc
);
392 OP(FILTER_OP_RETURN
):
403 OP(FILTER_OP_RSHIFT
):
404 OP(FILTER_OP_LSHIFT
):
405 OP(FILTER_OP_BIN_AND
):
406 OP(FILTER_OP_BIN_OR
):
407 OP(FILTER_OP_BIN_XOR
):
408 ERR("unsupported bytecode op %u\n",
409 (unsigned int) *(filter_opcode_t
*) pc
);
419 ERR("unsupported non-specialized bytecode op %u\n",
420 (unsigned int) *(filter_opcode_t
*) pc
);
424 OP(FILTER_OP_EQ_STRING
):
426 reg
[REG_R0
].v
= (reg_strcmp(reg
, "==") == 0);
427 reg
[REG_R0
].type
= REG_S64
;
428 next_pc
+= sizeof(struct binary_op
);
431 OP(FILTER_OP_NE_STRING
):
433 reg
[REG_R0
].v
= (reg_strcmp(reg
, "!=") != 0);
434 reg
[REG_R0
].type
= REG_S64
;
435 next_pc
+= sizeof(struct binary_op
);
438 OP(FILTER_OP_GT_STRING
):
440 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">") > 0);
441 reg
[REG_R0
].type
= REG_S64
;
442 next_pc
+= sizeof(struct binary_op
);
445 OP(FILTER_OP_LT_STRING
):
447 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<") < 0);
448 reg
[REG_R0
].type
= REG_S64
;
449 next_pc
+= sizeof(struct binary_op
);
452 OP(FILTER_OP_GE_STRING
):
454 reg
[REG_R0
].v
= (reg_strcmp(reg
, ">=") >= 0);
455 reg
[REG_R0
].type
= REG_S64
;
456 next_pc
+= sizeof(struct binary_op
);
459 OP(FILTER_OP_LE_STRING
):
461 reg
[REG_R0
].v
= (reg_strcmp(reg
, "<=") <= 0);
462 reg
[REG_R0
].type
= REG_S64
;
463 next_pc
+= sizeof(struct binary_op
);
467 OP(FILTER_OP_EQ_S64
):
469 reg
[REG_R0
].v
= (reg
[REG_R0
].v
== reg
[REG_R1
].v
);
470 reg
[REG_R0
].type
= REG_S64
;
471 next_pc
+= sizeof(struct binary_op
);
474 OP(FILTER_OP_NE_S64
):
476 reg
[REG_R0
].v
= (reg
[REG_R0
].v
!= reg
[REG_R1
].v
);
477 reg
[REG_R0
].type
= REG_S64
;
478 next_pc
+= sizeof(struct binary_op
);
481 OP(FILTER_OP_GT_S64
):
483 reg
[REG_R0
].v
= (reg
[REG_R0
].v
> reg
[REG_R1
].v
);
484 reg
[REG_R0
].type
= REG_S64
;
485 next_pc
+= sizeof(struct binary_op
);
488 OP(FILTER_OP_LT_S64
):
490 reg
[REG_R0
].v
= (reg
[REG_R0
].v
< reg
[REG_R1
].v
);
491 reg
[REG_R0
].type
= REG_S64
;
492 next_pc
+= sizeof(struct binary_op
);
495 OP(FILTER_OP_GE_S64
):
497 reg
[REG_R0
].v
= (reg
[REG_R0
].v
>= reg
[REG_R1
].v
);
498 reg
[REG_R0
].type
= REG_S64
;
499 next_pc
+= sizeof(struct binary_op
);
502 OP(FILTER_OP_LE_S64
):
504 reg
[REG_R0
].v
= (reg
[REG_R0
].v
<= reg
[REG_R1
].v
);
505 reg
[REG_R0
].type
= REG_S64
;
506 next_pc
+= sizeof(struct binary_op
);
510 OP(FILTER_OP_EQ_DOUBLE
):
512 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
513 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
514 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
515 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
516 reg
[REG_R0
].v
= (reg
[REG_R0
].d
== reg
[REG_R1
].d
);
517 reg
[REG_R0
].type
= REG_S64
;
518 next_pc
+= sizeof(struct binary_op
);
521 OP(FILTER_OP_NE_DOUBLE
):
523 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
524 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
525 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
526 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
527 reg
[REG_R0
].v
= (reg
[REG_R0
].d
!= reg
[REG_R1
].d
);
528 reg
[REG_R0
].type
= REG_S64
;
529 next_pc
+= sizeof(struct binary_op
);
532 OP(FILTER_OP_GT_DOUBLE
):
534 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
535 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
536 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
537 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
538 reg
[REG_R0
].v
= (reg
[REG_R0
].d
> reg
[REG_R1
].d
);
539 reg
[REG_R0
].type
= REG_S64
;
540 next_pc
+= sizeof(struct binary_op
);
543 OP(FILTER_OP_LT_DOUBLE
):
545 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
546 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
547 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
548 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
549 reg
[REG_R0
].v
= (reg
[REG_R0
].d
< reg
[REG_R1
].d
);
550 reg
[REG_R0
].type
= REG_S64
;
551 next_pc
+= sizeof(struct binary_op
);
554 OP(FILTER_OP_GE_DOUBLE
):
556 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
557 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
558 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
559 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
560 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
);
565 OP(FILTER_OP_LE_DOUBLE
):
567 if (unlikely(reg
[REG_R0
].type
== REG_S64
))
568 reg
[REG_R0
].d
= (double) reg
[REG_R0
].v
;
569 else if (unlikely(reg
[REG_R1
].type
== REG_S64
))
570 reg
[REG_R1
].d
= (double) reg
[REG_R1
].v
;
571 reg
[REG_R0
].v
= (reg
[REG_R0
].d
<= reg
[REG_R1
].d
);
572 reg
[REG_R0
].type
= REG_S64
;
573 next_pc
+= sizeof(struct binary_op
);
578 OP(FILTER_OP_UNARY_PLUS
):
579 OP(FILTER_OP_UNARY_MINUS
):
580 OP(FILTER_OP_UNARY_NOT
):
581 ERR("unsupported non-specialized bytecode op %u\n",
582 (unsigned int) *(filter_opcode_t
*) pc
);
587 OP(FILTER_OP_UNARY_PLUS_S64
):
588 OP(FILTER_OP_UNARY_PLUS_DOUBLE
):
590 next_pc
+= sizeof(struct unary_op
);
593 OP(FILTER_OP_UNARY_MINUS_S64
):
595 struct unary_op
*insn
= (struct unary_op
*) pc
;
597 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
598 next_pc
+= sizeof(struct unary_op
);
601 OP(FILTER_OP_UNARY_MINUS_DOUBLE
):
603 struct unary_op
*insn
= (struct unary_op
*) pc
;
605 reg
[insn
->reg
].d
= -reg
[insn
->reg
].d
;
606 next_pc
+= sizeof(struct unary_op
);
609 OP(FILTER_OP_UNARY_NOT_S64
):
611 struct unary_op
*insn
= (struct unary_op
*) pc
;
613 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
614 next_pc
+= sizeof(struct unary_op
);
617 OP(FILTER_OP_UNARY_NOT_DOUBLE
):
619 struct unary_op
*insn
= (struct unary_op
*) pc
;
621 reg
[insn
->reg
].d
= !reg
[insn
->reg
].d
;
622 next_pc
+= sizeof(struct unary_op
);
629 struct logical_op
*insn
= (struct logical_op
*) pc
;
631 /* If REG_R0 is 0, skip and evaluate to 0 */
632 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
== 0)
633 || unlikely(reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
== 0.0)) {
634 dbg_printf("Jumping to bytecode offset %u\n",
635 (unsigned int) insn
->skip_offset
);
636 next_pc
= start_pc
+ insn
->skip_offset
;
638 next_pc
+= sizeof(struct logical_op
);
644 struct logical_op
*insn
= (struct logical_op
*) pc
;
646 /* If REG_R0 is nonzero, skip and evaluate to 1 */
648 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
!= 0)
649 || unlikely(reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
!= 0.0)) {
651 dbg_printf("Jumping to bytecode offset %u\n",
652 (unsigned int) insn
->skip_offset
);
653 next_pc
= start_pc
+ insn
->skip_offset
;
655 next_pc
+= sizeof(struct logical_op
);
661 OP(FILTER_OP_LOAD_FIELD_REF_STRING
):
663 struct load_op
*insn
= (struct load_op
*) pc
;
664 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
666 dbg_printf("load field ref offset %u type string\n",
669 *(const char * const *) &filter_stack_data
[ref
->offset
];
670 reg
[insn
->reg
].type
= REG_STRING
;
671 reg
[insn
->reg
].seq_len
= UINT_MAX
;
672 reg
[insn
->reg
].literal
= 0;
673 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
674 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
678 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE
):
680 struct load_op
*insn
= (struct load_op
*) pc
;
681 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
683 dbg_printf("load field ref offset %u type sequence\n",
685 reg
[insn
->reg
].seq_len
=
686 *(unsigned long *) &filter_stack_data
[ref
->offset
];
688 *(const char **) (&filter_stack_data
[ref
->offset
689 + sizeof(unsigned long)]);
690 reg
[insn
->reg
].type
= REG_STRING
;
691 reg
[insn
->reg
].literal
= 0;
692 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
696 OP(FILTER_OP_LOAD_FIELD_REF_S64
):
698 struct load_op
*insn
= (struct load_op
*) pc
;
699 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
701 dbg_printf("load field ref offset %u type s64\n",
703 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
704 sizeof(struct literal_numeric
));
705 reg
[insn
->reg
].type
= REG_S64
;
706 reg
[insn
->reg
].literal
= 0;
707 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
708 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
712 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE
):
714 struct load_op
*insn
= (struct load_op
*) pc
;
715 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
717 dbg_printf("load field ref offset %u type double\n",
719 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
720 sizeof(struct literal_double
));
721 reg
[insn
->reg
].type
= REG_DOUBLE
;
722 reg
[insn
->reg
].literal
= 0;
723 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
724 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
728 OP(FILTER_OP_LOAD_STRING
):
730 struct load_op
*insn
= (struct load_op
*) pc
;
732 dbg_printf("load string %s\n", insn
->data
);
733 reg
[insn
->reg
].str
= insn
->data
;
734 reg
[insn
->reg
].type
= REG_STRING
;
735 reg
[insn
->reg
].seq_len
= UINT_MAX
;
736 reg
[insn
->reg
].literal
= 1;
737 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
741 OP(FILTER_OP_LOAD_S64
):
743 struct load_op
*insn
= (struct load_op
*) pc
;
745 memcpy(®
[insn
->reg
].v
, insn
->data
,
746 sizeof(struct literal_numeric
));
747 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
748 reg
[insn
->reg
].type
= REG_S64
;
749 reg
[insn
->reg
].literal
= 1;
750 next_pc
+= sizeof(struct load_op
)
751 + sizeof(struct literal_numeric
);
755 OP(FILTER_OP_LOAD_DOUBLE
):
757 struct load_op
*insn
= (struct load_op
*) pc
;
759 memcpy(®
[insn
->reg
].d
, insn
->data
,
760 sizeof(struct literal_double
));
761 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
762 reg
[insn
->reg
].type
= REG_DOUBLE
;
763 reg
[insn
->reg
].literal
= 1;
764 next_pc
+= sizeof(struct load_op
)
765 + sizeof(struct literal_double
);
771 /* return 0 (discard) on error */
778 int bin_op_compare_check(struct vreg reg
[NR_REG
], const char *str
)
780 switch (reg
[REG_R0
].type
) {
785 switch (reg
[REG_R1
].type
) {
798 switch (reg
[REG_R1
].type
) {
817 ERR("type mismatch for '%s' binary operator\n", str
);
822 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
824 void *pc
, *next_pc
, *start_pc
;
826 struct vreg reg
[NR_REG
];
829 for (i
= 0; i
< NR_REG
; i
++) {
830 reg
[i
].type
= REG_TYPE_UNKNOWN
;
834 start_pc
= &bytecode
->data
[0];
835 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
837 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
838 ERR("filter bytecode overflow\n");
842 dbg_printf("Validating op %s (%u)\n",
843 print_op((unsigned int) *(filter_opcode_t
*) pc
),
844 (unsigned int) *(filter_opcode_t
*) pc
);
845 switch (*(filter_opcode_t
*) pc
) {
846 case FILTER_OP_UNKNOWN
:
848 ERR("unknown bytecode op %u\n",
849 (unsigned int) *(filter_opcode_t
*) pc
);
853 case FILTER_OP_RETURN
:
862 case FILTER_OP_MINUS
:
863 case FILTER_OP_RSHIFT
:
864 case FILTER_OP_LSHIFT
:
865 case FILTER_OP_BIN_AND
:
866 case FILTER_OP_BIN_OR
:
867 case FILTER_OP_BIN_XOR
:
868 ERR("unsupported bytecode op %u\n",
869 (unsigned int) *(filter_opcode_t
*) pc
);
875 ret
= bin_op_compare_check(reg
, "==");
878 reg
[REG_R0
].type
= REG_S64
;
879 next_pc
+= sizeof(struct binary_op
);
884 ret
= bin_op_compare_check(reg
, "!=");
887 reg
[REG_R0
].type
= REG_S64
;
888 next_pc
+= sizeof(struct binary_op
);
893 ret
= bin_op_compare_check(reg
, ">");
896 reg
[REG_R0
].type
= REG_S64
;
897 next_pc
+= sizeof(struct binary_op
);
902 ret
= bin_op_compare_check(reg
, "<");
905 reg
[REG_R0
].type
= REG_S64
;
906 next_pc
+= sizeof(struct binary_op
);
911 ret
= bin_op_compare_check(reg
, ">=");
914 reg
[REG_R0
].type
= REG_S64
;
915 next_pc
+= sizeof(struct binary_op
);
920 ret
= bin_op_compare_check(reg
, "<=");
923 reg
[REG_R0
].type
= REG_S64
;
924 next_pc
+= sizeof(struct binary_op
);
928 case FILTER_OP_EQ_STRING
:
929 case FILTER_OP_NE_STRING
:
930 case FILTER_OP_GT_STRING
:
931 case FILTER_OP_LT_STRING
:
932 case FILTER_OP_GE_STRING
:
933 case FILTER_OP_LE_STRING
:
935 if (reg
[REG_R0
].type
!= REG_STRING
936 || reg
[REG_R1
].type
!= REG_STRING
) {
937 ERR("Unexpected register type for string comparator\n");
941 reg
[REG_R0
].type
= REG_S64
;
942 next_pc
+= sizeof(struct binary_op
);
946 case FILTER_OP_EQ_S64
:
947 case FILTER_OP_NE_S64
:
948 case FILTER_OP_GT_S64
:
949 case FILTER_OP_LT_S64
:
950 case FILTER_OP_GE_S64
:
951 case FILTER_OP_LE_S64
:
953 if (reg
[REG_R0
].type
!= REG_S64
954 || reg
[REG_R1
].type
!= REG_S64
) {
955 ERR("Unexpected register type for s64 comparator\n");
959 reg
[REG_R0
].type
= REG_S64
;
960 next_pc
+= sizeof(struct binary_op
);
964 case FILTER_OP_EQ_DOUBLE
:
965 case FILTER_OP_NE_DOUBLE
:
966 case FILTER_OP_GT_DOUBLE
:
967 case FILTER_OP_LT_DOUBLE
:
968 case FILTER_OP_GE_DOUBLE
:
969 case FILTER_OP_LE_DOUBLE
:
971 if ((reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R0
].type
!= REG_S64
)
972 || (reg
[REG_R1
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_S64
)) {
973 ERR("Unexpected register type for double comparator\n");
977 reg
[REG_R0
].type
= REG_DOUBLE
;
978 next_pc
+= sizeof(struct binary_op
);
983 case FILTER_OP_UNARY_PLUS
:
984 case FILTER_OP_UNARY_MINUS
:
985 case FILTER_OP_UNARY_NOT
:
987 struct unary_op
*insn
= (struct unary_op
*) pc
;
989 if (unlikely(insn
->reg
>= REG_ERROR
)) {
990 ERR("invalid register %u\n",
991 (unsigned int) insn
->reg
);
995 switch (reg
[insn
->reg
].type
) {
997 ERR("unknown register type\n");
1002 ERR("Unary op can only be applied to numeric or floating point registers\n");
1010 next_pc
+= sizeof(struct unary_op
);
1014 case FILTER_OP_UNARY_PLUS_S64
:
1015 case FILTER_OP_UNARY_MINUS_S64
:
1016 case FILTER_OP_UNARY_NOT_S64
:
1018 struct unary_op
*insn
= (struct unary_op
*) pc
;
1020 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1021 ERR("invalid register %u\n",
1022 (unsigned int) insn
->reg
);
1026 if (reg
[insn
->reg
].type
!= REG_S64
) {
1027 ERR("Invalid register type\n");
1031 next_pc
+= sizeof(struct unary_op
);
1035 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1036 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1037 case FILTER_OP_UNARY_NOT_DOUBLE
:
1039 struct unary_op
*insn
= (struct unary_op
*) pc
;
1041 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1042 ERR("invalid register %u\n",
1043 (unsigned int) insn
->reg
);
1047 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
1048 ERR("Invalid register type\n");
1052 next_pc
+= sizeof(struct unary_op
);
1060 struct logical_op
*insn
= (struct logical_op
*) pc
;
1062 if (unlikely(reg
[REG_R0
].type
== REG_TYPE_UNKNOWN
1063 || reg
[REG_R1
].type
== REG_TYPE_UNKNOWN
1064 || reg
[REG_R0
].type
== REG_STRING
1065 || reg
[REG_R1
].type
== REG_STRING
)) {
1066 ERR("Logical comparator can only be applied to numeric and floating point registers\n");
1071 dbg_printf("Validate jumping to bytecode offset %u\n",
1072 (unsigned int) insn
->skip_offset
);
1073 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
1074 ERR("Loops are not allowed in bytecode\n");
1078 next_pc
+= sizeof(struct logical_op
);
1083 case FILTER_OP_LOAD_FIELD_REF
:
1085 ERR("Unknown field ref type\n");
1089 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1090 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1092 struct load_op
*insn
= (struct load_op
*) pc
;
1093 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1095 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1096 ERR("invalid register %u\n",
1097 (unsigned int) insn
->reg
);
1101 dbg_printf("Validate load field ref offset %u type string\n",
1103 reg
[insn
->reg
].type
= REG_STRING
;
1104 reg
[insn
->reg
].literal
= 0;
1105 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1108 case FILTER_OP_LOAD_FIELD_REF_S64
:
1110 struct load_op
*insn
= (struct load_op
*) pc
;
1111 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1113 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1114 ERR("invalid register %u\n",
1115 (unsigned int) insn
->reg
);
1119 dbg_printf("Validate load field ref offset %u type s64\n",
1121 reg
[insn
->reg
].type
= REG_S64
;
1122 reg
[insn
->reg
].literal
= 0;
1123 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1126 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1128 struct load_op
*insn
= (struct load_op
*) pc
;
1129 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1131 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1132 ERR("invalid register %u\n",
1133 (unsigned int) insn
->reg
);
1137 dbg_printf("Validate load field ref offset %u type double\n",
1139 reg
[insn
->reg
].type
= REG_DOUBLE
;
1140 reg
[insn
->reg
].literal
= 0;
1141 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1145 case FILTER_OP_LOAD_STRING
:
1147 struct load_op
*insn
= (struct load_op
*) pc
;
1149 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1150 ERR("invalid register %u\n",
1151 (unsigned int) insn
->reg
);
1155 reg
[insn
->reg
].type
= REG_STRING
;
1156 reg
[insn
->reg
].literal
= 1;
1157 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1161 case FILTER_OP_LOAD_S64
:
1163 struct load_op
*insn
= (struct load_op
*) pc
;
1165 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1166 ERR("invalid register %u\n",
1167 (unsigned int) insn
->reg
);
1171 reg
[insn
->reg
].type
= REG_S64
;
1172 reg
[insn
->reg
].literal
= 1;
1173 next_pc
+= sizeof(struct load_op
)
1174 + sizeof(struct literal_numeric
);
1178 case FILTER_OP_LOAD_DOUBLE
:
1180 struct load_op
*insn
= (struct load_op
*) pc
;
1182 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1183 ERR("invalid register %u\n",
1184 (unsigned int) insn
->reg
);
1188 reg
[insn
->reg
].type
= REG_DOUBLE
;
1189 reg
[insn
->reg
].literal
= 1;
1190 next_pc
+= sizeof(struct load_op
)
1191 + sizeof(struct literal_double
);
1201 int lttng_filter_specialize_bytecode(struct bytecode_runtime
*bytecode
)
1203 void *pc
, *next_pc
, *start_pc
;
1205 struct vreg reg
[NR_REG
];
1208 for (i
= 0; i
< NR_REG
; i
++) {
1209 reg
[i
].type
= REG_TYPE_UNKNOWN
;
1213 start_pc
= &bytecode
->data
[0];
1214 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1216 switch (*(filter_opcode_t
*) pc
) {
1217 case FILTER_OP_UNKNOWN
:
1219 ERR("unknown bytecode op %u\n",
1220 (unsigned int) *(filter_opcode_t
*) pc
);
1224 case FILTER_OP_RETURN
:
1232 case FILTER_OP_PLUS
:
1233 case FILTER_OP_MINUS
:
1234 case FILTER_OP_RSHIFT
:
1235 case FILTER_OP_LSHIFT
:
1236 case FILTER_OP_BIN_AND
:
1237 case FILTER_OP_BIN_OR
:
1238 case FILTER_OP_BIN_XOR
:
1239 ERR("unsupported bytecode op %u\n",
1240 (unsigned int) *(filter_opcode_t
*) pc
);
1246 struct binary_op
*insn
= (struct binary_op
*) pc
;
1248 switch(reg
[REG_R0
].type
) {
1250 ERR("unknown register type\n");
1255 insn
->op
= FILTER_OP_EQ_STRING
;
1258 if (reg
[REG_R1
].type
== REG_S64
)
1259 insn
->op
= FILTER_OP_EQ_S64
;
1261 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1264 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1267 reg
[REG_R0
].type
= REG_S64
;
1268 next_pc
+= sizeof(struct binary_op
);
1274 struct binary_op
*insn
= (struct binary_op
*) pc
;
1276 switch(reg
[REG_R0
].type
) {
1278 ERR("unknown register type\n");
1283 insn
->op
= FILTER_OP_NE_STRING
;
1286 if (reg
[REG_R1
].type
== REG_S64
)
1287 insn
->op
= FILTER_OP_NE_S64
;
1289 insn
->op
= FILTER_OP_NE_DOUBLE
;
1292 insn
->op
= FILTER_OP_NE_DOUBLE
;
1295 reg
[REG_R0
].type
= REG_S64
;
1296 next_pc
+= sizeof(struct binary_op
);
1302 struct binary_op
*insn
= (struct binary_op
*) pc
;
1304 switch(reg
[REG_R0
].type
) {
1306 ERR("unknown register type\n");
1311 insn
->op
= FILTER_OP_GT_STRING
;
1314 if (reg
[REG_R1
].type
== REG_S64
)
1315 insn
->op
= FILTER_OP_GT_S64
;
1317 insn
->op
= FILTER_OP_GT_DOUBLE
;
1320 insn
->op
= FILTER_OP_GT_DOUBLE
;
1323 reg
[REG_R0
].type
= REG_S64
;
1324 next_pc
+= sizeof(struct binary_op
);
1330 struct binary_op
*insn
= (struct binary_op
*) pc
;
1332 switch(reg
[REG_R0
].type
) {
1334 ERR("unknown register type\n");
1339 insn
->op
= FILTER_OP_LT_STRING
;
1342 if (reg
[REG_R1
].type
== REG_S64
)
1343 insn
->op
= FILTER_OP_LT_S64
;
1345 insn
->op
= FILTER_OP_LT_DOUBLE
;
1348 insn
->op
= FILTER_OP_LT_DOUBLE
;
1351 reg
[REG_R0
].type
= REG_S64
;
1352 next_pc
+= sizeof(struct binary_op
);
1358 struct binary_op
*insn
= (struct binary_op
*) pc
;
1360 switch(reg
[REG_R0
].type
) {
1362 ERR("unknown register type\n");
1367 insn
->op
= FILTER_OP_GE_STRING
;
1370 if (reg
[REG_R1
].type
== REG_S64
)
1371 insn
->op
= FILTER_OP_GE_S64
;
1373 insn
->op
= FILTER_OP_GE_DOUBLE
;
1376 insn
->op
= FILTER_OP_GE_DOUBLE
;
1379 reg
[REG_R0
].type
= REG_S64
;
1380 next_pc
+= sizeof(struct binary_op
);
1385 struct binary_op
*insn
= (struct binary_op
*) pc
;
1387 switch(reg
[REG_R0
].type
) {
1389 ERR("unknown register type\n");
1394 insn
->op
= FILTER_OP_LE_STRING
;
1397 if (reg
[REG_R1
].type
== REG_S64
)
1398 insn
->op
= FILTER_OP_LE_S64
;
1400 insn
->op
= FILTER_OP_LE_DOUBLE
;
1403 insn
->op
= FILTER_OP_LE_DOUBLE
;
1406 reg
[REG_R0
].type
= REG_S64
;
1407 next_pc
+= sizeof(struct binary_op
);
1411 case FILTER_OP_EQ_STRING
:
1412 case FILTER_OP_NE_STRING
:
1413 case FILTER_OP_GT_STRING
:
1414 case FILTER_OP_LT_STRING
:
1415 case FILTER_OP_GE_STRING
:
1416 case FILTER_OP_LE_STRING
:
1417 case FILTER_OP_EQ_S64
:
1418 case FILTER_OP_NE_S64
:
1419 case FILTER_OP_GT_S64
:
1420 case FILTER_OP_LT_S64
:
1421 case FILTER_OP_GE_S64
:
1422 case FILTER_OP_LE_S64
:
1423 case FILTER_OP_EQ_DOUBLE
:
1424 case FILTER_OP_NE_DOUBLE
:
1425 case FILTER_OP_GT_DOUBLE
:
1426 case FILTER_OP_LT_DOUBLE
:
1427 case FILTER_OP_GE_DOUBLE
:
1428 case FILTER_OP_LE_DOUBLE
:
1430 reg
[REG_R0
].type
= REG_S64
;
1431 next_pc
+= sizeof(struct binary_op
);
1436 case FILTER_OP_UNARY_PLUS
:
1438 struct unary_op
*insn
= (struct unary_op
*) pc
;
1440 switch(reg
[insn
->reg
].type
) {
1442 ERR("unknown register type\n");
1447 insn
->op
= FILTER_OP_UNARY_PLUS_S64
;
1450 insn
->op
= FILTER_OP_UNARY_PLUS_DOUBLE
;
1456 case FILTER_OP_UNARY_MINUS
:
1458 struct unary_op
*insn
= (struct unary_op
*) pc
;
1460 switch(reg
[insn
->reg
].type
) {
1462 ERR("unknown register type\n");
1467 insn
->op
= FILTER_OP_UNARY_MINUS_S64
;
1470 insn
->op
= FILTER_OP_UNARY_MINUS_DOUBLE
;
1476 case FILTER_OP_UNARY_NOT
:
1478 struct unary_op
*insn
= (struct unary_op
*) pc
;
1480 switch(reg
[insn
->reg
].type
) {
1482 ERR("unknown register type\n");
1487 insn
->op
= FILTER_OP_UNARY_NOT_S64
;
1490 insn
->op
= FILTER_OP_UNARY_NOT_DOUBLE
;
1496 case FILTER_OP_UNARY_PLUS_S64
:
1497 case FILTER_OP_UNARY_MINUS_S64
:
1498 case FILTER_OP_UNARY_NOT_S64
:
1499 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1500 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1501 case FILTER_OP_UNARY_NOT_DOUBLE
:
1503 next_pc
+= sizeof(struct unary_op
);
1511 next_pc
+= sizeof(struct logical_op
);
1516 case FILTER_OP_LOAD_FIELD_REF
:
1518 ERR("Unknown field ref type\n");
1522 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1523 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1525 struct load_op
*insn
= (struct load_op
*) pc
;
1527 reg
[insn
->reg
].type
= REG_STRING
;
1528 reg
[insn
->reg
].literal
= 0;
1529 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1532 case FILTER_OP_LOAD_FIELD_REF_S64
:
1534 struct load_op
*insn
= (struct load_op
*) pc
;
1536 reg
[insn
->reg
].type
= REG_S64
;
1537 reg
[insn
->reg
].literal
= 0;
1538 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1541 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1543 struct load_op
*insn
= (struct load_op
*) pc
;
1545 reg
[insn
->reg
].type
= REG_DOUBLE
;
1546 reg
[insn
->reg
].literal
= 0;
1547 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1551 case FILTER_OP_LOAD_STRING
:
1553 struct load_op
*insn
= (struct load_op
*) pc
;
1555 reg
[insn
->reg
].type
= REG_STRING
;
1556 reg
[insn
->reg
].literal
= 1;
1557 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1561 case FILTER_OP_LOAD_S64
:
1563 struct load_op
*insn
= (struct load_op
*) pc
;
1565 reg
[insn
->reg
].type
= REG_S64
;
1566 reg
[insn
->reg
].literal
= 1;
1567 next_pc
+= sizeof(struct load_op
)
1568 + sizeof(struct literal_numeric
);
1572 case FILTER_OP_LOAD_DOUBLE
:
1574 struct load_op
*insn
= (struct load_op
*) pc
;
1576 reg
[insn
->reg
].type
= REG_DOUBLE
;
1577 reg
[insn
->reg
].literal
= 1;
1578 next_pc
+= sizeof(struct load_op
)
1579 + sizeof(struct literal_double
);
1591 int apply_field_reloc(struct ltt_event
*event
,
1592 struct bytecode_runtime
*runtime
,
1593 uint32_t runtime_len
,
1594 uint32_t reloc_offset
,
1595 const char *field_name
)
1597 const struct lttng_event_desc
*desc
;
1598 const struct lttng_event_field
*fields
, *field
= NULL
;
1599 unsigned int nr_fields
, i
;
1600 struct field_ref
*field_ref
;
1602 uint32_t field_offset
= 0;
1604 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1606 /* Ensure that the reloc is within the code */
1607 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1610 /* Lookup event by name */
1614 fields
= desc
->fields
;
1617 nr_fields
= desc
->nr_fields
;
1618 for (i
= 0; i
< nr_fields
; i
++) {
1619 if (!strcmp(fields
[i
].name
, field_name
)) {
1623 /* compute field offset */
1624 switch (fields
[i
].type
.atype
) {
1627 field_offset
+= sizeof(int64_t);
1630 case atype_sequence
:
1631 field_offset
+= sizeof(unsigned long);
1632 field_offset
+= sizeof(void *);
1635 field_offset
+= sizeof(void *);
1638 field_offset
+= sizeof(double);
1647 /* Check if field offset is too large for 16-bit offset */
1648 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1652 op
= (struct load_op
*) &runtime
->data
[reloc_offset
];
1653 field_ref
= (struct field_ref
*) op
->data
;
1654 switch (field
->type
.atype
) {
1657 op
->op
= FILTER_OP_LOAD_FIELD_REF_S64
;
1660 case atype_sequence
:
1661 op
->op
= FILTER_OP_LOAD_FIELD_REF_SEQUENCE
;
1664 op
->op
= FILTER_OP_LOAD_FIELD_REF_STRING
;
1667 op
->op
= FILTER_OP_LOAD_FIELD_REF_DOUBLE
;
1673 field_ref
->offset
= (uint16_t) field_offset
;
1678 * Take a bytecode with reloc table and link it to an event to create a
1682 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1683 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1685 int ret
, offset
, next_offset
;
1686 struct bytecode_runtime
*runtime
= NULL
;
1687 size_t runtime_alloc_len
;
1689 if (!filter_bytecode
)
1691 /* Even is not connected to any description */
1694 /* Bytecode already linked */
1695 if (event
->filter
|| event
->filter_data
)
1698 dbg_printf("Linking\n");
1700 /* We don't need the reloc table in the runtime */
1701 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
1702 runtime
= zmalloc(runtime_alloc_len
);
1707 runtime
->len
= filter_bytecode
->reloc_offset
;
1708 /* copy original bytecode */
1709 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
1711 * apply relocs. Those are a uint16_t (offset in bytecode)
1712 * followed by a string (field name).
1714 for (offset
= filter_bytecode
->reloc_offset
;
1715 offset
< filter_bytecode
->len
;
1716 offset
= next_offset
) {
1717 uint16_t reloc_offset
=
1718 *(uint16_t *) &filter_bytecode
->data
[offset
];
1719 const char *field_name
=
1720 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
1722 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1726 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1728 /* Validate bytecode */
1729 ret
= lttng_filter_validate_bytecode(runtime
);
1733 /* Specialize bytecode */
1734 ret
= lttng_filter_specialize_bytecode(runtime
);
1738 event
->filter_data
= runtime
;
1739 event
->filter
= lttng_filter_interpret_bytecode
;
1743 event
->filter
= lttng_filter_false
;
1748 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1749 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1753 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1755 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1760 * Link bytecode to all events for a wildcard. Skips events that already
1761 * have a bytecode linked.
1762 * We do not set each event's filter_bytecode field, because they do not
1763 * own the filter_bytecode: the wildcard owns it.
1765 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1767 struct ltt_event
*event
;
1770 if (!wildcard
->filter_bytecode
)
1773 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1776 ret
= _lttng_filter_event_link_bytecode(event
,
1777 wildcard
->filter_bytecode
);
1779 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1787 * Need to attach filter to an event before starting tracing for the
1788 * session. We own the filter_bytecode if we return success.
1790 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1791 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1793 if (event
->chan
->session
->been_active
)
1795 if (event
->filter_bytecode
)
1797 event
->filter_bytecode
= filter_bytecode
;
1802 * Need to attach filter to a wildcard before starting tracing for the
1803 * session. We own the filter_bytecode if we return success.
1805 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1806 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1808 if (wildcard
->chan
->session
->been_active
)
1810 if (wildcard
->filter_bytecode
)
1812 wildcard
->filter_bytecode
= filter_bytecode
;