2 * filter-visitor-generate-ir.c
4 * LTTng filter generate intermediate representation
6 * Copyright 2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * SPDX-License-Identifier: LGPL-2.1-only
12 #include "filter-ast.hpp"
13 #include "filter-ir.hpp"
14 #include "filter-parser.hpp"
16 #include <common/compat/errno.hpp>
17 #include <common/macros.hpp>
18 #include <common/string-utils/string-utils.hpp>
27 generate_ir_recursive(struct filter_parser_ctx
*ctx
, struct filter_node
*node
, enum ir_side side
);
29 static struct ir_op
*make_op_root(struct ir_op
*child
, enum ir_side side
)
33 op
= zmalloc
<ir_op
>();
36 switch (child
->data_type
) {
39 fprintf(stderr
, "[error] Unknown root child data type\n");
43 fprintf(stderr
, "[error] String cannot be root data type\n");
47 case IR_DATA_FIELD_REF
:
48 case IR_DATA_GET_CONTEXT_REF
:
49 case IR_DATA_EXPRESSION
:
55 op
->data_type
= child
->data_type
;
56 op
->signedness
= child
->signedness
;
57 op
->u
.root
.child
= child
;
61 static enum ir_load_string_type
get_literal_string_type(const char *string
)
65 if (strutils_is_star_glob_pattern(string
)) {
66 if (strutils_is_star_at_the_end_only_glob_pattern(string
)) {
67 return IR_LOAD_STRING_TYPE_GLOB_STAR_END
;
70 return IR_LOAD_STRING_TYPE_GLOB_STAR
;
73 return IR_LOAD_STRING_TYPE_PLAIN
;
76 static struct ir_op
*make_op_load_string(const char *string
, enum ir_side side
)
80 op
= zmalloc
<ir_op
>();
84 op
->data_type
= IR_DATA_STRING
;
85 op
->signedness
= IR_SIGN_UNKNOWN
;
87 op
->u
.load
.u
.string
.type
= get_literal_string_type(string
);
88 op
->u
.load
.u
.string
.value
= strdup(string
);
89 if (!op
->u
.load
.u
.string
.value
) {
96 static struct ir_op
*make_op_load_numeric(int64_t v
, enum ir_side side
)
100 op
= zmalloc
<ir_op
>();
104 op
->data_type
= IR_DATA_NUMERIC
;
105 /* TODO: for now, all numeric values are signed */
106 op
->signedness
= IR_SIGNED
;
108 op
->u
.load
.u
.num
= v
;
112 static struct ir_op
*make_op_load_float(double v
, enum ir_side side
)
116 op
= zmalloc
<ir_op
>();
120 op
->data_type
= IR_DATA_FLOAT
;
121 op
->signedness
= IR_SIGN_UNKNOWN
;
123 op
->u
.load
.u
.flt
= v
;
127 static void free_load_expression(struct ir_load_expression
*load_expression
)
129 struct ir_load_expression_op
*exp_op
;
131 if (!load_expression
)
133 exp_op
= load_expression
->child
;
135 struct ir_load_expression_op
*prev_exp_op
;
139 switch (exp_op
->type
) {
140 case IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT
:
141 case IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT
:
142 case IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT
:
143 case IR_LOAD_EXPRESSION_GET_INDEX
:
144 case IR_LOAD_EXPRESSION_LOAD_FIELD
:
146 case IR_LOAD_EXPRESSION_GET_SYMBOL
:
147 free(exp_op
->u
.symbol
);
150 prev_exp_op
= exp_op
;
151 exp_op
= exp_op
->next
;
154 free(load_expression
);
158 * Returns the first node of the chain, after initializing the next
161 static struct filter_node
*load_expression_get_forward_chain(struct filter_node
*node
)
163 struct filter_node
*prev_node
;
166 LTTNG_ASSERT(node
->type
== NODE_EXPRESSION
);
168 node
= node
->u
.expression
.prev
;
172 node
->u
.expression
.next
= prev_node
;
177 static struct ir_load_expression
*create_load_expression(struct filter_node
*node
)
179 struct ir_load_expression
*load_exp
;
180 struct ir_load_expression_op
*load_exp_op
, *prev_op
;
183 /* Get forward chain. */
184 node
= load_expression_get_forward_chain(node
);
187 load_exp
= zmalloc
<ir_load_expression
>();
192 load_exp_op
= zmalloc
<ir_load_expression_op
>();
195 load_exp
->child
= load_exp_op
;
196 str
= node
->u
.expression
.u
.string
;
197 if (!strcmp(str
, "$ctx")) {
198 load_exp_op
->type
= IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT
;
199 node
= node
->u
.expression
.next
;
201 fprintf(stderr
, "[error] Expecting identifier after \'%s\'\n", str
);
204 str
= node
->u
.expression
.u
.string
;
205 } else if (!strcmp(str
, "$app")) {
206 load_exp_op
->type
= IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT
;
207 node
= node
->u
.expression
.next
;
209 fprintf(stderr
, "[error] Expecting identifier after \'%s\'\n", str
);
212 str
= node
->u
.expression
.u
.string
;
213 } else if (str
[0] == '$') {
214 fprintf(stderr
, "[error] Unexpected identifier \'%s\'\n", str
);
217 load_exp_op
->type
= IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT
;
221 struct filter_node
*bracket_node
;
223 prev_op
= load_exp_op
;
224 load_exp_op
= zmalloc
<ir_load_expression_op
>();
227 prev_op
->next
= load_exp_op
;
228 load_exp_op
->type
= IR_LOAD_EXPRESSION_GET_SYMBOL
;
229 load_exp_op
->u
.symbol
= strdup(str
);
230 if (!load_exp_op
->u
.symbol
)
233 /* Explore brackets from current node. */
234 for (bracket_node
= node
->u
.expression
.next_bracket
; bracket_node
!= NULL
;
235 bracket_node
= bracket_node
->u
.expression
.next_bracket
) {
236 prev_op
= load_exp_op
;
237 if (bracket_node
->type
!= NODE_EXPRESSION
||
238 bracket_node
->u
.expression
.type
!= AST_EXP_CONSTANT
) {
240 "[error] Expecting constant index in array expression\n");
243 load_exp_op
= zmalloc
<ir_load_expression_op
>();
246 prev_op
->next
= load_exp_op
;
247 load_exp_op
->type
= IR_LOAD_EXPRESSION_GET_INDEX
;
248 load_exp_op
->u
.index
= bracket_node
->u
.expression
.u
.constant
;
250 /* Go to next chain element. */
251 node
= node
->u
.expression
.next
;
254 str
= node
->u
.expression
.u
.string
;
256 /* Add final load field */
257 prev_op
= load_exp_op
;
258 load_exp_op
= zmalloc
<ir_load_expression_op
>();
261 prev_op
->next
= load_exp_op
;
262 load_exp_op
->type
= IR_LOAD_EXPRESSION_LOAD_FIELD
;
266 free_load_expression(load_exp
);
270 static struct ir_op
*make_op_load_expression(struct filter_node
*node
, enum ir_side side
)
274 op
= zmalloc
<ir_op
>();
278 op
->data_type
= IR_DATA_EXPRESSION
;
279 op
->signedness
= IR_SIGN_DYN
;
281 op
->u
.load
.u
.expression
= create_load_expression(node
);
282 if (!op
->u
.load
.u
.expression
) {
288 free_load_expression(op
->u
.load
.u
.expression
);
293 static struct ir_op
*make_op_unary(enum unary_op_type unary_op_type
,
295 enum ir_op_signedness signedness
,
299 struct ir_op
*op
= NULL
;
301 if (child
->data_type
== IR_DATA_STRING
) {
303 "[error] unary operation '%s' not allowed on string literal\n",
308 op
= zmalloc
<ir_op
>();
311 op
->op
= IR_OP_UNARY
;
312 op
->data_type
= child
->data_type
;
313 op
->signedness
= signedness
;
315 op
->u
.unary
.type
= unary_op_type
;
316 op
->u
.unary
.child
= child
;
325 * unary + is pretty much useless.
327 static struct ir_op
*make_op_unary_plus(struct ir_op
*child
, enum ir_side side
)
329 return make_op_unary(AST_UNARY_PLUS
, "+", child
->signedness
, child
, side
);
332 static struct ir_op
*make_op_unary_minus(struct ir_op
*child
, enum ir_side side
)
334 return make_op_unary(AST_UNARY_MINUS
, "-", child
->signedness
, child
, side
);
337 static struct ir_op
*make_op_unary_not(struct ir_op
*child
, enum ir_side side
)
339 return make_op_unary(AST_UNARY_NOT
, "!", child
->signedness
, child
, side
);
342 static struct ir_op
*make_op_unary_bit_not(struct ir_op
*child
, enum ir_side side
)
344 return make_op_unary(AST_UNARY_BIT_NOT
, "~", child
->signedness
, child
, side
);
347 static struct ir_op
*make_op_binary_compare(enum op_type bin_op_type
,
353 struct ir_op
*op
= NULL
;
355 if (left
->data_type
== IR_DATA_UNKNOWN
|| right
->data_type
== IR_DATA_UNKNOWN
) {
356 fprintf(stderr
, "[error] binary operation '%s' has unknown operand type\n", op_str
);
359 if ((left
->data_type
== IR_DATA_STRING
&&
360 (right
->data_type
== IR_DATA_NUMERIC
|| right
->data_type
== IR_DATA_FLOAT
)) ||
361 ((left
->data_type
== IR_DATA_NUMERIC
|| left
->data_type
== IR_DATA_FLOAT
) &&
362 right
->data_type
== IR_DATA_STRING
)) {
363 fprintf(stderr
, "[error] binary operation '%s' operand type mismatch\n", op_str
);
367 op
= zmalloc
<ir_op
>();
370 op
->op
= IR_OP_BINARY
;
371 op
->u
.binary
.type
= bin_op_type
;
372 op
->u
.binary
.left
= left
;
373 op
->u
.binary
.right
= right
;
375 /* we return a boolean, represented as signed numeric */
376 op
->data_type
= IR_DATA_NUMERIC
;
377 op
->signedness
= IR_SIGNED
;
387 static struct ir_op
*make_op_binary_eq(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
389 return make_op_binary_compare(AST_OP_EQ
, "==", left
, right
, side
);
392 static struct ir_op
*make_op_binary_ne(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
394 return make_op_binary_compare(AST_OP_NE
, "!=", left
, right
, side
);
397 static struct ir_op
*make_op_binary_gt(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
399 return make_op_binary_compare(AST_OP_GT
, ">", left
, right
, side
);
402 static struct ir_op
*make_op_binary_lt(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
404 return make_op_binary_compare(AST_OP_LT
, "<", left
, right
, side
);
407 static struct ir_op
*make_op_binary_ge(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
409 return make_op_binary_compare(AST_OP_GE
, ">=", left
, right
, side
);
412 static struct ir_op
*make_op_binary_le(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
414 return make_op_binary_compare(AST_OP_LE
, "<=", left
, right
, side
);
417 static struct ir_op
*make_op_binary_logical(enum op_type bin_op_type
,
423 struct ir_op
*op
= NULL
;
425 if (left
->data_type
== IR_DATA_UNKNOWN
|| right
->data_type
== IR_DATA_UNKNOWN
) {
426 fprintf(stderr
, "[error] binary operation '%s' has unknown operand type\n", op_str
);
429 if (left
->data_type
== IR_DATA_STRING
|| right
->data_type
== IR_DATA_STRING
) {
431 "[error] logical binary operation '%s' cannot have string operand\n",
436 op
= zmalloc
<ir_op
>();
439 op
->op
= IR_OP_LOGICAL
;
440 op
->u
.binary
.type
= bin_op_type
;
441 op
->u
.binary
.left
= left
;
442 op
->u
.binary
.right
= right
;
444 /* we return a boolean, represented as signed numeric */
445 op
->data_type
= IR_DATA_NUMERIC
;
446 op
->signedness
= IR_SIGNED
;
456 static struct ir_op
*make_op_binary_bitwise(enum op_type bin_op_type
,
462 struct ir_op
*op
= NULL
;
464 if (left
->data_type
== IR_DATA_UNKNOWN
|| right
->data_type
== IR_DATA_UNKNOWN
) {
466 "[error] bitwise binary operation '%s' has unknown operand type\n",
470 if (left
->data_type
== IR_DATA_STRING
|| right
->data_type
== IR_DATA_STRING
) {
472 "[error] bitwise binary operation '%s' cannot have string operand\n",
476 if (left
->data_type
== IR_DATA_FLOAT
|| right
->data_type
== IR_DATA_FLOAT
) {
478 "[error] bitwise binary operation '%s' cannot have floating point operand\n",
483 op
= zmalloc
<ir_op
>();
486 op
->op
= IR_OP_BINARY
;
487 op
->u
.binary
.type
= bin_op_type
;
488 op
->u
.binary
.left
= left
;
489 op
->u
.binary
.right
= right
;
491 /* we return a signed numeric */
492 op
->data_type
= IR_DATA_NUMERIC
;
493 op
->signedness
= IR_SIGNED
;
503 static struct ir_op
*
504 make_op_binary_logical_and(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
506 return make_op_binary_logical(AST_OP_AND
, "&&", left
, right
, side
);
509 static struct ir_op
*
510 make_op_binary_logical_or(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
512 return make_op_binary_logical(AST_OP_OR
, "||", left
, right
, side
);
515 static struct ir_op
*
516 make_op_binary_bitwise_rshift(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
518 return make_op_binary_bitwise(AST_OP_BIT_RSHIFT
, ">>", left
, right
, side
);
521 static struct ir_op
*
522 make_op_binary_bitwise_lshift(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
524 return make_op_binary_bitwise(AST_OP_BIT_LSHIFT
, "<<", left
, right
, side
);
527 static struct ir_op
*
528 make_op_binary_bitwise_and(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
530 return make_op_binary_bitwise(AST_OP_BIT_AND
, "&", left
, right
, side
);
533 static struct ir_op
*
534 make_op_binary_bitwise_or(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
536 return make_op_binary_bitwise(AST_OP_BIT_OR
, "|", left
, right
, side
);
539 static struct ir_op
*
540 make_op_binary_bitwise_xor(struct ir_op
*left
, struct ir_op
*right
, enum ir_side side
)
542 return make_op_binary_bitwise(AST_OP_BIT_XOR
, "^", left
, right
, side
);
545 static void filter_free_ir_recursive(struct ir_op
*op
)
552 fprintf(stderr
, "[error] Unknown op type in %s\n", __func__
);
555 filter_free_ir_recursive(op
->u
.root
.child
);
558 switch (op
->data_type
) {
560 free(op
->u
.load
.u
.string
.value
);
562 case IR_DATA_FIELD_REF
: /* fall-through */
563 case IR_DATA_GET_CONTEXT_REF
:
564 free(op
->u
.load
.u
.ref
);
566 case IR_DATA_EXPRESSION
:
567 free_load_expression(op
->u
.load
.u
.expression
);
573 filter_free_ir_recursive(op
->u
.unary
.child
);
576 filter_free_ir_recursive(op
->u
.binary
.left
);
577 filter_free_ir_recursive(op
->u
.binary
.right
);
580 filter_free_ir_recursive(op
->u
.logical
.left
);
581 filter_free_ir_recursive(op
->u
.logical
.right
);
587 static struct ir_op
*
588 make_expression(struct filter_parser_ctx
*ctx
, struct filter_node
*node
, enum ir_side side
)
590 switch (node
->u
.expression
.type
) {
591 case AST_EXP_UNKNOWN
:
593 fprintf(stderr
, "[error] %s: unknown expression type\n", __func__
);
597 return make_op_load_string(node
->u
.expression
.u
.string
, side
);
598 case AST_EXP_CONSTANT
:
599 return make_op_load_numeric(node
->u
.expression
.u
.constant
, side
);
600 case AST_EXP_FLOAT_CONSTANT
:
601 return make_op_load_float(node
->u
.expression
.u
.float_constant
, side
);
602 case AST_EXP_IDENTIFIER
:
603 case AST_EXP_GLOBAL_IDENTIFIER
:
604 return make_op_load_expression(node
, side
);
606 return generate_ir_recursive(ctx
, node
->u
.expression
.u
.child
, side
);
610 static struct ir_op
*
611 make_op(struct filter_parser_ctx
*ctx
, struct filter_node
*node
, enum ir_side side
)
613 struct ir_op
*op
= NULL
, *lchild
, *rchild
;
614 const char *op_str
= "?";
616 switch (node
->u
.op
.type
) {
619 fprintf(stderr
, "[error] %s: unknown binary op type\n", __func__
);
623 * The following binary operators other than comparators and
624 * logical and/or are not supported yet.
628 goto error_not_supported
;
631 goto error_not_supported
;
634 goto error_not_supported
;
637 goto error_not_supported
;
640 goto error_not_supported
;
642 case AST_OP_BIT_RSHIFT
:
643 case AST_OP_BIT_LSHIFT
:
647 lchild
= generate_ir_recursive(ctx
, node
->u
.op
.lchild
, IR_LEFT
);
650 rchild
= generate_ir_recursive(ctx
, node
->u
.op
.rchild
, IR_RIGHT
);
652 filter_free_ir_recursive(lchild
);
663 lchild
= generate_ir_recursive(ctx
, node
->u
.op
.lchild
, IR_LEFT
);
666 rchild
= generate_ir_recursive(ctx
, node
->u
.op
.rchild
, IR_RIGHT
);
668 filter_free_ir_recursive(lchild
);
676 * Both children considered as left, since we need to
679 lchild
= generate_ir_recursive(ctx
, node
->u
.op
.lchild
, IR_LEFT
);
682 rchild
= generate_ir_recursive(ctx
, node
->u
.op
.rchild
, IR_LEFT
);
684 filter_free_ir_recursive(lchild
);
690 switch (node
->u
.op
.type
) {
692 op
= make_op_binary_logical_and(lchild
, rchild
, side
);
695 op
= make_op_binary_logical_or(lchild
, rchild
, side
);
698 op
= make_op_binary_eq(lchild
, rchild
, side
);
701 op
= make_op_binary_ne(lchild
, rchild
, side
);
704 op
= make_op_binary_gt(lchild
, rchild
, side
);
707 op
= make_op_binary_lt(lchild
, rchild
, side
);
710 op
= make_op_binary_ge(lchild
, rchild
, side
);
713 op
= make_op_binary_le(lchild
, rchild
, side
);
715 case AST_OP_BIT_RSHIFT
:
716 op
= make_op_binary_bitwise_rshift(lchild
, rchild
, side
);
718 case AST_OP_BIT_LSHIFT
:
719 op
= make_op_binary_bitwise_lshift(lchild
, rchild
, side
);
722 op
= make_op_binary_bitwise_and(lchild
, rchild
, side
);
725 op
= make_op_binary_bitwise_or(lchild
, rchild
, side
);
728 op
= make_op_binary_bitwise_xor(lchild
, rchild
, side
);
735 filter_free_ir_recursive(rchild
);
736 filter_free_ir_recursive(lchild
);
741 fprintf(stderr
, "[error] %s: binary operation '%s' not supported\n", __func__
, op_str
);
745 static struct ir_op
*
746 make_unary_op(struct filter_parser_ctx
*ctx
, struct filter_node
*node
, enum ir_side side
)
748 switch (node
->u
.unary_op
.type
) {
749 case AST_UNARY_UNKNOWN
:
751 fprintf(stderr
, "[error] %s: unknown unary op type\n", __func__
);
756 struct ir_op
*op
, *child
;
758 child
= generate_ir_recursive(ctx
, node
->u
.unary_op
.child
, side
);
761 op
= make_op_unary_plus(child
, side
);
763 filter_free_ir_recursive(child
);
768 case AST_UNARY_MINUS
:
770 struct ir_op
*op
, *child
;
772 child
= generate_ir_recursive(ctx
, node
->u
.unary_op
.child
, side
);
775 op
= make_op_unary_minus(child
, side
);
777 filter_free_ir_recursive(child
);
784 struct ir_op
*op
, *child
;
786 child
= generate_ir_recursive(ctx
, node
->u
.unary_op
.child
, side
);
789 op
= make_op_unary_not(child
, side
);
791 filter_free_ir_recursive(child
);
796 case AST_UNARY_BIT_NOT
:
798 struct ir_op
*op
, *child
;
800 child
= generate_ir_recursive(ctx
, node
->u
.unary_op
.child
, side
);
803 op
= make_op_unary_bit_not(child
, side
);
805 filter_free_ir_recursive(child
);
815 static struct ir_op
*
816 generate_ir_recursive(struct filter_parser_ctx
*ctx
, struct filter_node
*node
, enum ir_side side
)
818 switch (node
->type
) {
821 fprintf(stderr
, "[error] %s: unknown node type\n", __func__
);
826 struct ir_op
*op
, *child
;
828 child
= generate_ir_recursive(ctx
, node
->u
.root
.child
, side
);
831 op
= make_op_root(child
, side
);
833 filter_free_ir_recursive(child
);
838 case NODE_EXPRESSION
:
839 return make_expression(ctx
, node
, side
);
841 return make_op(ctx
, node
, side
);
843 return make_unary_op(ctx
, node
, side
);
848 void filter_ir_free(struct filter_parser_ctx
*ctx
)
850 filter_free_ir_recursive(ctx
->ir_root
);
854 int filter_visitor_ir_generate(struct filter_parser_ctx
*ctx
)
858 op
= generate_ir_recursive(ctx
, &ctx
->ast
->root
, IR_LEFT
);