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
):
580 next_pc
+= sizeof(struct unary_op
);
583 OP(FILTER_OP_UNARY_MINUS
):
585 struct unary_op
*insn
= (struct unary_op
*) pc
;
587 switch (reg
[insn
->reg
].type
) {
589 ERR("unknown register type\n");
594 ERR("Unary minus can only be applied to numeric or floating point registers\n");
598 reg
[insn
->reg
].v
= -reg
[insn
->reg
].v
;
601 reg
[insn
->reg
].d
= -reg
[insn
->reg
].d
;
604 next_pc
+= sizeof(struct unary_op
);
607 OP(FILTER_OP_UNARY_NOT
):
609 struct unary_op
*insn
= (struct unary_op
*) pc
;
611 switch (reg
[insn
->reg
].type
) {
613 ERR("unknown register type\n");
618 ERR("Unary not can only be applied to numeric or floating point registers\n");
622 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
625 reg
[insn
->reg
].d
= !reg
[insn
->reg
].d
;
628 reg
[insn
->reg
].v
= !reg
[insn
->reg
].v
;
629 next_pc
+= sizeof(struct unary_op
);
635 struct logical_op
*insn
= (struct logical_op
*) pc
;
637 /* If REG_R0 is 0, skip and evaluate to 0 */
638 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
== 0)
639 || unlikely(reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
== 0.0)) {
640 dbg_printf("Jumping to bytecode offset %u\n",
641 (unsigned int) insn
->skip_offset
);
642 next_pc
= start_pc
+ insn
->skip_offset
;
644 next_pc
+= sizeof(struct logical_op
);
650 struct logical_op
*insn
= (struct logical_op
*) pc
;
652 /* If REG_R0 is nonzero, skip and evaluate to 1 */
654 if ((reg
[REG_R0
].type
== REG_S64
&& reg
[REG_R0
].v
!= 0)
655 || unlikely(reg
[REG_R0
].type
== REG_DOUBLE
&& reg
[REG_R0
].d
!= 0.0)) {
657 dbg_printf("Jumping to bytecode offset %u\n",
658 (unsigned int) insn
->skip_offset
);
659 next_pc
= start_pc
+ insn
->skip_offset
;
661 next_pc
+= sizeof(struct logical_op
);
667 OP(FILTER_OP_LOAD_FIELD_REF_STRING
):
669 struct load_op
*insn
= (struct load_op
*) pc
;
670 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
672 dbg_printf("load field ref offset %u type string\n",
675 *(const char * const *) &filter_stack_data
[ref
->offset
];
676 reg
[insn
->reg
].type
= REG_STRING
;
677 reg
[insn
->reg
].seq_len
= UINT_MAX
;
678 reg
[insn
->reg
].literal
= 0;
679 dbg_printf("ref load string %s\n", reg
[insn
->reg
].str
);
680 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
684 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE
):
686 struct load_op
*insn
= (struct load_op
*) pc
;
687 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
689 dbg_printf("load field ref offset %u type sequence\n",
691 reg
[insn
->reg
].seq_len
=
692 *(unsigned long *) &filter_stack_data
[ref
->offset
];
694 *(const char **) (&filter_stack_data
[ref
->offset
695 + sizeof(unsigned long)]);
696 reg
[insn
->reg
].type
= REG_STRING
;
697 reg
[insn
->reg
].literal
= 0;
698 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
702 OP(FILTER_OP_LOAD_FIELD_REF_S64
):
704 struct load_op
*insn
= (struct load_op
*) pc
;
705 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
707 dbg_printf("load field ref offset %u type s64\n",
709 memcpy(®
[insn
->reg
].v
, &filter_stack_data
[ref
->offset
],
710 sizeof(struct literal_numeric
));
711 reg
[insn
->reg
].type
= REG_S64
;
712 reg
[insn
->reg
].literal
= 0;
713 dbg_printf("ref load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
714 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
718 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE
):
720 struct load_op
*insn
= (struct load_op
*) pc
;
721 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
723 dbg_printf("load field ref offset %u type double\n",
725 memcpy(®
[insn
->reg
].d
, &filter_stack_data
[ref
->offset
],
726 sizeof(struct literal_double
));
727 reg
[insn
->reg
].type
= REG_DOUBLE
;
728 reg
[insn
->reg
].literal
= 0;
729 dbg_printf("ref load double %g\n", reg
[insn
->reg
].d
);
730 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
734 OP(FILTER_OP_LOAD_STRING
):
736 struct load_op
*insn
= (struct load_op
*) pc
;
738 dbg_printf("load string %s\n", insn
->data
);
739 reg
[insn
->reg
].str
= insn
->data
;
740 reg
[insn
->reg
].type
= REG_STRING
;
741 reg
[insn
->reg
].seq_len
= UINT_MAX
;
742 reg
[insn
->reg
].literal
= 1;
743 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
747 OP(FILTER_OP_LOAD_S64
):
749 struct load_op
*insn
= (struct load_op
*) pc
;
751 memcpy(®
[insn
->reg
].v
, insn
->data
,
752 sizeof(struct literal_numeric
));
753 dbg_printf("load s64 %" PRIi64
"\n", reg
[insn
->reg
].v
);
754 reg
[insn
->reg
].type
= REG_S64
;
755 reg
[insn
->reg
].literal
= 1;
756 next_pc
+= sizeof(struct load_op
)
757 + sizeof(struct literal_numeric
);
761 OP(FILTER_OP_LOAD_DOUBLE
):
763 struct load_op
*insn
= (struct load_op
*) pc
;
765 memcpy(®
[insn
->reg
].d
, insn
->data
,
766 sizeof(struct literal_double
));
767 dbg_printf("load s64 %g\n", reg
[insn
->reg
].d
);
768 reg
[insn
->reg
].type
= REG_DOUBLE
;
769 reg
[insn
->reg
].literal
= 1;
770 next_pc
+= sizeof(struct load_op
)
771 + sizeof(struct literal_double
);
777 /* return 0 (discard) on error */
784 int bin_op_compare_check(struct vreg reg
[NR_REG
], const char *str
)
786 switch (reg
[REG_R0
].type
) {
791 switch (reg
[REG_R1
].type
) {
804 switch (reg
[REG_R1
].type
) {
823 ERR("type mismatch for '%s' binary operator\n", str
);
828 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
830 void *pc
, *next_pc
, *start_pc
;
832 struct vreg reg
[NR_REG
];
835 for (i
= 0; i
< NR_REG
; i
++) {
836 reg
[i
].type
= REG_TYPE_UNKNOWN
;
840 start_pc
= &bytecode
->data
[0];
841 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
843 if (unlikely(pc
>= start_pc
+ bytecode
->len
)) {
844 ERR("filter bytecode overflow\n");
848 dbg_printf("Validating op %s (%u)\n",
849 print_op((unsigned int) *(filter_opcode_t
*) pc
),
850 (unsigned int) *(filter_opcode_t
*) pc
);
851 switch (*(filter_opcode_t
*) pc
) {
852 case FILTER_OP_UNKNOWN
:
854 ERR("unknown bytecode op %u\n",
855 (unsigned int) *(filter_opcode_t
*) pc
);
859 case FILTER_OP_RETURN
:
868 case FILTER_OP_MINUS
:
869 case FILTER_OP_RSHIFT
:
870 case FILTER_OP_LSHIFT
:
871 case FILTER_OP_BIN_AND
:
872 case FILTER_OP_BIN_OR
:
873 case FILTER_OP_BIN_XOR
:
874 ERR("unsupported bytecode op %u\n",
875 (unsigned int) *(filter_opcode_t
*) pc
);
881 ret
= bin_op_compare_check(reg
, "==");
884 reg
[REG_R0
].type
= REG_S64
;
885 next_pc
+= sizeof(struct binary_op
);
890 ret
= bin_op_compare_check(reg
, "!=");
893 reg
[REG_R0
].type
= REG_S64
;
894 next_pc
+= sizeof(struct binary_op
);
899 ret
= bin_op_compare_check(reg
, ">");
902 reg
[REG_R0
].type
= REG_S64
;
903 next_pc
+= sizeof(struct binary_op
);
908 ret
= bin_op_compare_check(reg
, "<");
911 reg
[REG_R0
].type
= REG_S64
;
912 next_pc
+= sizeof(struct binary_op
);
917 ret
= bin_op_compare_check(reg
, ">=");
920 reg
[REG_R0
].type
= REG_S64
;
921 next_pc
+= sizeof(struct binary_op
);
926 ret
= bin_op_compare_check(reg
, "<=");
929 reg
[REG_R0
].type
= REG_S64
;
930 next_pc
+= sizeof(struct binary_op
);
934 case FILTER_OP_EQ_STRING
:
935 case FILTER_OP_NE_STRING
:
936 case FILTER_OP_GT_STRING
:
937 case FILTER_OP_LT_STRING
:
938 case FILTER_OP_GE_STRING
:
939 case FILTER_OP_LE_STRING
:
941 if (reg
[REG_R0
].type
!= REG_STRING
942 || reg
[REG_R1
].type
!= REG_STRING
) {
943 ERR("Unexpected register type for string comparator\n");
947 reg
[REG_R0
].type
= REG_S64
;
948 next_pc
+= sizeof(struct binary_op
);
952 case FILTER_OP_EQ_S64
:
953 case FILTER_OP_NE_S64
:
954 case FILTER_OP_GT_S64
:
955 case FILTER_OP_LT_S64
:
956 case FILTER_OP_GE_S64
:
957 case FILTER_OP_LE_S64
:
959 if (reg
[REG_R0
].type
!= REG_S64
960 || reg
[REG_R1
].type
!= REG_S64
) {
961 ERR("Unexpected register type for s64 comparator\n");
965 reg
[REG_R0
].type
= REG_S64
;
966 next_pc
+= sizeof(struct binary_op
);
970 case FILTER_OP_EQ_DOUBLE
:
971 case FILTER_OP_NE_DOUBLE
:
972 case FILTER_OP_GT_DOUBLE
:
973 case FILTER_OP_LT_DOUBLE
:
974 case FILTER_OP_GE_DOUBLE
:
975 case FILTER_OP_LE_DOUBLE
:
977 if ((reg
[REG_R0
].type
!= REG_DOUBLE
&& reg
[REG_R0
].type
!= REG_S64
)
978 || (reg
[REG_R1
].type
!= REG_DOUBLE
&& reg
[REG_R1
].type
!= REG_S64
)) {
979 ERR("Unexpected register type for double comparator\n");
983 reg
[REG_R0
].type
= REG_DOUBLE
;
984 next_pc
+= sizeof(struct binary_op
);
989 case FILTER_OP_UNARY_PLUS
:
990 case FILTER_OP_UNARY_MINUS
:
991 case FILTER_OP_UNARY_NOT
:
993 struct unary_op
*insn
= (struct unary_op
*) pc
;
995 if (unlikely(insn
->reg
>= REG_ERROR
)) {
996 ERR("invalid register %u\n",
997 (unsigned int) insn
->reg
);
1001 switch (reg
[insn
->reg
].type
) {
1003 ERR("unknown register type\n");
1008 ERR("Unary op can only be applied to numeric or floating point registers\n");
1016 next_pc
+= sizeof(struct unary_op
);
1020 case FILTER_OP_UNARY_PLUS_S64
:
1021 case FILTER_OP_UNARY_MINUS_S64
:
1022 case FILTER_OP_UNARY_NOT_S64
:
1024 struct unary_op
*insn
= (struct unary_op
*) pc
;
1026 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1027 ERR("invalid register %u\n",
1028 (unsigned int) insn
->reg
);
1032 if (reg
[insn
->reg
].type
!= REG_S64
) {
1033 ERR("Invalid register type\n");
1037 next_pc
+= sizeof(struct unary_op
);
1041 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1042 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1043 case FILTER_OP_UNARY_NOT_DOUBLE
:
1045 struct unary_op
*insn
= (struct unary_op
*) pc
;
1047 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1048 ERR("invalid register %u\n",
1049 (unsigned int) insn
->reg
);
1053 if (reg
[insn
->reg
].type
!= REG_DOUBLE
) {
1054 ERR("Invalid register type\n");
1058 next_pc
+= sizeof(struct unary_op
);
1066 struct logical_op
*insn
= (struct logical_op
*) pc
;
1068 if (unlikely(reg
[REG_R0
].type
== REG_TYPE_UNKNOWN
1069 || reg
[REG_R1
].type
== REG_TYPE_UNKNOWN
1070 || reg
[REG_R0
].type
== REG_STRING
1071 || reg
[REG_R1
].type
== REG_STRING
)) {
1072 ERR("Logical comparator can only be applied to numeric and floating point registers\n");
1077 dbg_printf("Validate jumping to bytecode offset %u\n",
1078 (unsigned int) insn
->skip_offset
);
1079 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
1080 ERR("Loops are not allowed in bytecode\n");
1084 next_pc
+= sizeof(struct logical_op
);
1089 case FILTER_OP_LOAD_FIELD_REF
:
1091 ERR("Unknown field ref type\n");
1095 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1096 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1098 struct load_op
*insn
= (struct load_op
*) pc
;
1099 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1101 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1102 ERR("invalid register %u\n",
1103 (unsigned int) insn
->reg
);
1107 dbg_printf("Validate load field ref offset %u type string\n",
1109 reg
[insn
->reg
].type
= REG_STRING
;
1110 reg
[insn
->reg
].literal
= 0;
1111 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1114 case FILTER_OP_LOAD_FIELD_REF_S64
:
1116 struct load_op
*insn
= (struct load_op
*) pc
;
1117 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1119 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1120 ERR("invalid register %u\n",
1121 (unsigned int) insn
->reg
);
1125 dbg_printf("Validate load field ref offset %u type s64\n",
1127 reg
[insn
->reg
].type
= REG_S64
;
1128 reg
[insn
->reg
].literal
= 0;
1129 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1132 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1134 struct load_op
*insn
= (struct load_op
*) pc
;
1135 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1137 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1138 ERR("invalid register %u\n",
1139 (unsigned int) insn
->reg
);
1143 dbg_printf("Validate load field ref offset %u type double\n",
1145 reg
[insn
->reg
].type
= REG_DOUBLE
;
1146 reg
[insn
->reg
].literal
= 0;
1147 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1151 case FILTER_OP_LOAD_STRING
:
1153 struct load_op
*insn
= (struct load_op
*) pc
;
1155 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1156 ERR("invalid register %u\n",
1157 (unsigned int) insn
->reg
);
1161 reg
[insn
->reg
].type
= REG_STRING
;
1162 reg
[insn
->reg
].literal
= 1;
1163 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1167 case FILTER_OP_LOAD_S64
:
1169 struct load_op
*insn
= (struct load_op
*) pc
;
1171 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1172 ERR("invalid register %u\n",
1173 (unsigned int) insn
->reg
);
1177 reg
[insn
->reg
].type
= REG_S64
;
1178 reg
[insn
->reg
].literal
= 1;
1179 next_pc
+= sizeof(struct load_op
)
1180 + sizeof(struct literal_numeric
);
1184 case FILTER_OP_LOAD_DOUBLE
:
1186 struct load_op
*insn
= (struct load_op
*) pc
;
1188 if (unlikely(insn
->reg
>= REG_ERROR
)) {
1189 ERR("invalid register %u\n",
1190 (unsigned int) insn
->reg
);
1194 reg
[insn
->reg
].type
= REG_DOUBLE
;
1195 reg
[insn
->reg
].literal
= 1;
1196 next_pc
+= sizeof(struct load_op
)
1197 + sizeof(struct literal_double
);
1207 int lttng_filter_specialize_bytecode(struct bytecode_runtime
*bytecode
)
1209 void *pc
, *next_pc
, *start_pc
;
1211 struct vreg reg
[NR_REG
];
1214 for (i
= 0; i
< NR_REG
; i
++) {
1215 reg
[i
].type
= REG_TYPE_UNKNOWN
;
1219 start_pc
= &bytecode
->data
[0];
1220 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1222 switch (*(filter_opcode_t
*) pc
) {
1223 case FILTER_OP_UNKNOWN
:
1225 ERR("unknown bytecode op %u\n",
1226 (unsigned int) *(filter_opcode_t
*) pc
);
1230 case FILTER_OP_RETURN
:
1238 case FILTER_OP_PLUS
:
1239 case FILTER_OP_MINUS
:
1240 case FILTER_OP_RSHIFT
:
1241 case FILTER_OP_LSHIFT
:
1242 case FILTER_OP_BIN_AND
:
1243 case FILTER_OP_BIN_OR
:
1244 case FILTER_OP_BIN_XOR
:
1245 ERR("unsupported bytecode op %u\n",
1246 (unsigned int) *(filter_opcode_t
*) pc
);
1252 struct binary_op
*insn
= (struct binary_op
*) pc
;
1254 switch(reg
[REG_R0
].type
) {
1256 ERR("unknown register type\n");
1261 insn
->op
= FILTER_OP_EQ_STRING
;
1264 if (reg
[REG_R1
].type
== REG_S64
)
1265 insn
->op
= FILTER_OP_EQ_S64
;
1267 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1270 insn
->op
= FILTER_OP_EQ_DOUBLE
;
1273 reg
[REG_R0
].type
= REG_S64
;
1274 next_pc
+= sizeof(struct binary_op
);
1280 struct binary_op
*insn
= (struct binary_op
*) pc
;
1282 switch(reg
[REG_R0
].type
) {
1284 ERR("unknown register type\n");
1289 insn
->op
= FILTER_OP_NE_STRING
;
1292 if (reg
[REG_R1
].type
== REG_S64
)
1293 insn
->op
= FILTER_OP_NE_S64
;
1295 insn
->op
= FILTER_OP_NE_DOUBLE
;
1298 insn
->op
= FILTER_OP_NE_DOUBLE
;
1301 reg
[REG_R0
].type
= REG_S64
;
1302 next_pc
+= sizeof(struct binary_op
);
1308 struct binary_op
*insn
= (struct binary_op
*) pc
;
1310 switch(reg
[REG_R0
].type
) {
1312 ERR("unknown register type\n");
1317 insn
->op
= FILTER_OP_GT_STRING
;
1320 if (reg
[REG_R1
].type
== REG_S64
)
1321 insn
->op
= FILTER_OP_GT_S64
;
1323 insn
->op
= FILTER_OP_GT_DOUBLE
;
1326 insn
->op
= FILTER_OP_GT_DOUBLE
;
1329 reg
[REG_R0
].type
= REG_S64
;
1330 next_pc
+= sizeof(struct binary_op
);
1336 struct binary_op
*insn
= (struct binary_op
*) pc
;
1338 switch(reg
[REG_R0
].type
) {
1340 ERR("unknown register type\n");
1345 insn
->op
= FILTER_OP_LT_STRING
;
1348 if (reg
[REG_R1
].type
== REG_S64
)
1349 insn
->op
= FILTER_OP_LT_S64
;
1351 insn
->op
= FILTER_OP_LT_DOUBLE
;
1354 insn
->op
= FILTER_OP_LT_DOUBLE
;
1357 reg
[REG_R0
].type
= REG_S64
;
1358 next_pc
+= sizeof(struct binary_op
);
1364 struct binary_op
*insn
= (struct binary_op
*) pc
;
1366 switch(reg
[REG_R0
].type
) {
1368 ERR("unknown register type\n");
1373 insn
->op
= FILTER_OP_GE_STRING
;
1376 if (reg
[REG_R1
].type
== REG_S64
)
1377 insn
->op
= FILTER_OP_GE_S64
;
1379 insn
->op
= FILTER_OP_GE_DOUBLE
;
1382 insn
->op
= FILTER_OP_GE_DOUBLE
;
1385 reg
[REG_R0
].type
= REG_S64
;
1386 next_pc
+= sizeof(struct binary_op
);
1391 struct binary_op
*insn
= (struct binary_op
*) pc
;
1393 switch(reg
[REG_R0
].type
) {
1395 ERR("unknown register type\n");
1400 insn
->op
= FILTER_OP_LE_STRING
;
1403 if (reg
[REG_R1
].type
== REG_S64
)
1404 insn
->op
= FILTER_OP_LE_S64
;
1406 insn
->op
= FILTER_OP_LE_DOUBLE
;
1409 insn
->op
= FILTER_OP_LE_DOUBLE
;
1412 reg
[REG_R0
].type
= REG_S64
;
1413 next_pc
+= sizeof(struct binary_op
);
1417 case FILTER_OP_EQ_STRING
:
1418 case FILTER_OP_NE_STRING
:
1419 case FILTER_OP_GT_STRING
:
1420 case FILTER_OP_LT_STRING
:
1421 case FILTER_OP_GE_STRING
:
1422 case FILTER_OP_LE_STRING
:
1423 case FILTER_OP_EQ_S64
:
1424 case FILTER_OP_NE_S64
:
1425 case FILTER_OP_GT_S64
:
1426 case FILTER_OP_LT_S64
:
1427 case FILTER_OP_GE_S64
:
1428 case FILTER_OP_LE_S64
:
1429 case FILTER_OP_EQ_DOUBLE
:
1430 case FILTER_OP_NE_DOUBLE
:
1431 case FILTER_OP_GT_DOUBLE
:
1432 case FILTER_OP_LT_DOUBLE
:
1433 case FILTER_OP_GE_DOUBLE
:
1434 case FILTER_OP_LE_DOUBLE
:
1436 reg
[REG_R0
].type
= REG_S64
;
1437 next_pc
+= sizeof(struct binary_op
);
1443 case FILTER_OP_UNARY_PLUS
:
1445 struct unary_op
*insn
= (struct unary_op
*) pc
;
1447 switch(reg
[insn
->reg
].type
) {
1449 ERR("unknown register type\n");
1454 insn
->op
= FILTER_OP_UNARY_PLUS_S64
;
1457 insn
->op
= FILTER_OP_UNARY_PLUS_DOUBLE
;
1463 case FILTER_OP_UNARY_MINUS
:
1465 struct unary_op
*insn
= (struct unary_op
*) pc
;
1467 switch(reg
[insn
->reg
].type
) {
1469 ERR("unknown register type\n");
1474 insn
->op
= FILTER_OP_UNARY_MINUS_S64
;
1477 insn
->op
= FILTER_OP_UNARY_MINUS_DOUBLE
;
1483 case FILTER_OP_UNARY_NOT
:
1485 struct unary_op
*insn
= (struct unary_op
*) pc
;
1487 switch(reg
[insn
->reg
].type
) {
1489 ERR("unknown register type\n");
1494 insn
->op
= FILTER_OP_UNARY_NOT_S64
;
1497 insn
->op
= FILTER_OP_UNARY_NOT_DOUBLE
;
1503 case FILTER_OP_UNARY_PLUS_S64
:
1504 case FILTER_OP_UNARY_MINUS_S64
:
1505 case FILTER_OP_UNARY_NOT_S64
:
1506 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1507 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1508 case FILTER_OP_UNARY_NOT_DOUBLE
:
1510 next_pc
+= sizeof(struct unary_op
);
1518 next_pc
+= sizeof(struct logical_op
);
1523 case FILTER_OP_LOAD_FIELD_REF
:
1525 ERR("Unknown field ref type\n");
1529 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1530 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1532 struct load_op
*insn
= (struct load_op
*) pc
;
1534 reg
[insn
->reg
].type
= REG_STRING
;
1535 reg
[insn
->reg
].literal
= 0;
1536 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1539 case FILTER_OP_LOAD_FIELD_REF_S64
:
1541 struct load_op
*insn
= (struct load_op
*) pc
;
1543 reg
[insn
->reg
].type
= REG_S64
;
1544 reg
[insn
->reg
].literal
= 0;
1545 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1548 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1550 struct load_op
*insn
= (struct load_op
*) pc
;
1552 reg
[insn
->reg
].type
= REG_DOUBLE
;
1553 reg
[insn
->reg
].literal
= 0;
1554 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1558 case FILTER_OP_LOAD_STRING
:
1560 struct load_op
*insn
= (struct load_op
*) pc
;
1562 reg
[insn
->reg
].type
= REG_STRING
;
1563 reg
[insn
->reg
].literal
= 1;
1564 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1568 case FILTER_OP_LOAD_S64
:
1570 struct load_op
*insn
= (struct load_op
*) pc
;
1572 reg
[insn
->reg
].type
= REG_S64
;
1573 reg
[insn
->reg
].literal
= 1;
1574 next_pc
+= sizeof(struct load_op
)
1575 + sizeof(struct literal_numeric
);
1579 case FILTER_OP_LOAD_DOUBLE
:
1581 struct load_op
*insn
= (struct load_op
*) pc
;
1583 reg
[insn
->reg
].type
= REG_DOUBLE
;
1584 reg
[insn
->reg
].literal
= 1;
1585 next_pc
+= sizeof(struct load_op
)
1586 + sizeof(struct literal_double
);
1598 int apply_field_reloc(struct ltt_event
*event
,
1599 struct bytecode_runtime
*runtime
,
1600 uint32_t runtime_len
,
1601 uint32_t reloc_offset
,
1602 const char *field_name
)
1604 const struct lttng_event_desc
*desc
;
1605 const struct lttng_event_field
*fields
, *field
= NULL
;
1606 unsigned int nr_fields
, i
;
1607 struct field_ref
*field_ref
;
1609 uint32_t field_offset
= 0;
1611 dbg_printf("Apply reloc: %u %s\n", reloc_offset
, field_name
);
1613 /* Ensure that the reloc is within the code */
1614 if (runtime_len
- reloc_offset
< sizeof(uint16_t))
1617 /* Lookup event by name */
1621 fields
= desc
->fields
;
1624 nr_fields
= desc
->nr_fields
;
1625 for (i
= 0; i
< nr_fields
; i
++) {
1626 if (!strcmp(fields
[i
].name
, field_name
)) {
1630 /* compute field offset */
1631 switch (fields
[i
].type
.atype
) {
1634 field_offset
+= sizeof(int64_t);
1637 case atype_sequence
:
1638 field_offset
+= sizeof(unsigned long);
1639 field_offset
+= sizeof(void *);
1642 field_offset
+= sizeof(void *);
1645 field_offset
+= sizeof(double);
1654 /* Check if field offset is too large for 16-bit offset */
1655 if (field_offset
> FILTER_BYTECODE_MAX_LEN
)
1659 op
= (struct load_op
*) &runtime
->data
[reloc_offset
];
1660 field_ref
= (struct field_ref
*) op
->data
;
1661 switch (field
->type
.atype
) {
1664 op
->op
= FILTER_OP_LOAD_FIELD_REF_S64
;
1667 case atype_sequence
:
1668 op
->op
= FILTER_OP_LOAD_FIELD_REF_SEQUENCE
;
1671 op
->op
= FILTER_OP_LOAD_FIELD_REF_STRING
;
1674 op
->op
= FILTER_OP_LOAD_FIELD_REF_DOUBLE
;
1680 field_ref
->offset
= (uint16_t) field_offset
;
1685 * Take a bytecode with reloc table and link it to an event to create a
1689 int _lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1690 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1692 int ret
, offset
, next_offset
;
1693 struct bytecode_runtime
*runtime
= NULL
;
1694 size_t runtime_alloc_len
;
1696 if (!filter_bytecode
)
1698 /* Even is not connected to any description */
1701 /* Bytecode already linked */
1702 if (event
->filter
|| event
->filter_data
)
1705 dbg_printf("Linking\n");
1707 /* We don't need the reloc table in the runtime */
1708 runtime_alloc_len
= sizeof(*runtime
) + filter_bytecode
->reloc_offset
;
1709 runtime
= zmalloc(runtime_alloc_len
);
1714 runtime
->len
= filter_bytecode
->reloc_offset
;
1715 /* copy original bytecode */
1716 memcpy(runtime
->data
, filter_bytecode
->data
, runtime
->len
);
1718 * apply relocs. Those are a uint16_t (offset in bytecode)
1719 * followed by a string (field name).
1721 for (offset
= filter_bytecode
->reloc_offset
;
1722 offset
< filter_bytecode
->len
;
1723 offset
= next_offset
) {
1724 uint16_t reloc_offset
=
1725 *(uint16_t *) &filter_bytecode
->data
[offset
];
1726 const char *field_name
=
1727 (const char *) &filter_bytecode
->data
[offset
+ sizeof(uint16_t)];
1729 ret
= apply_field_reloc(event
, runtime
, runtime
->len
, reloc_offset
, field_name
);
1733 next_offset
= offset
+ sizeof(uint16_t) + strlen(field_name
) + 1;
1735 /* Validate bytecode */
1736 ret
= lttng_filter_validate_bytecode(runtime
);
1740 /* Specialize bytecode */
1741 ret
= lttng_filter_specialize_bytecode(runtime
);
1745 event
->filter_data
= runtime
;
1746 event
->filter
= lttng_filter_interpret_bytecode
;
1750 event
->filter
= lttng_filter_false
;
1755 void lttng_filter_event_link_bytecode(struct ltt_event
*event
,
1756 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1760 ret
= _lttng_filter_event_link_bytecode(event
, filter_bytecode
);
1762 fprintf(stderr
, "[lttng filter] error linking event bytecode\n");
1767 * Link bytecode to all events for a wildcard. Skips events that already
1768 * have a bytecode linked.
1769 * We do not set each event's filter_bytecode field, because they do not
1770 * own the filter_bytecode: the wildcard owns it.
1772 void lttng_filter_wildcard_link_bytecode(struct session_wildcard
*wildcard
)
1774 struct ltt_event
*event
;
1777 if (!wildcard
->filter_bytecode
)
1780 cds_list_for_each_entry(event
, &wildcard
->events
, wildcard_list
) {
1783 ret
= _lttng_filter_event_link_bytecode(event
,
1784 wildcard
->filter_bytecode
);
1786 fprintf(stderr
, "[lttng filter] error linking wildcard bytecode\n");
1794 * Need to attach filter to an event before starting tracing for the
1795 * session. We own the filter_bytecode if we return success.
1797 int lttng_filter_event_attach_bytecode(struct ltt_event
*event
,
1798 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1800 if (event
->chan
->session
->been_active
)
1802 if (event
->filter_bytecode
)
1804 event
->filter_bytecode
= filter_bytecode
;
1809 * Need to attach filter to a wildcard before starting tracing for the
1810 * session. We own the filter_bytecode if we return success.
1812 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard
*wildcard
,
1813 struct lttng_ust_filter_bytecode
*filter_bytecode
)
1815 if (wildcard
->chan
->session
->been_active
)
1817 if (wildcard
->filter_bytecode
)
1819 wildcard
->filter_bytecode
= filter_bytecode
;