SoW-2020-0002: Trace Hit Counters: trigger error reporting integration
[lttng-tools.git] / src / common / filter / filter-visitor-generate-bytecode.c
index 699273c3d984f7e9aba6f4ee51b0d77e2fa666d1..458b9d042e73cd60a40f469c40c5793554f93ff4 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <common/align.h>
-#include <common/compat/string.h>
 
-#include "filter-bytecode.h"
-#include "filter-ir.h"
+#include "common/align.h"
+#include "common/bytecode/bytecode.h"
+#include "common/compat/string.h"
+#include "common/macros.h"
 #include "filter-ast.h"
-
-#include <common/macros.h>
+#include "filter-ir.h"
 
 #ifndef max_t
 #define max_t(type, a, b)      ((type) ((a) > (b) ? (a) : (b)))
 #endif
 
-#define INIT_ALLOC_SIZE                4
-
 static
 int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx,
                struct ir_op *node);
 
-static inline int get_count_order(unsigned int count)
-{
-       int order;
-
-       order = lttng_fls(count) - 1;
-       if (count & (count - 1))
-               order++;
-       return order;
-}
-
-static
-int bytecode_init(struct lttng_filter_bytecode_alloc **fb)
-{
-       uint32_t alloc_len;
-
-       alloc_len = sizeof(struct lttng_filter_bytecode_alloc) + INIT_ALLOC_SIZE;
-       *fb = calloc(alloc_len, 1);
-       if (!*fb) {
-               return -ENOMEM;
-       } else {
-               (*fb)->alloc_len = alloc_len;
-               return 0;
-       }
-}
-
 static
-int32_t bytecode_reserve(struct lttng_filter_bytecode_alloc **fb, uint32_t align, uint32_t len)
-{
-       int32_t ret;
-       uint32_t padding = offset_align((*fb)->b.len, align);
-       uint32_t new_len = (*fb)->b.len + padding + len;
-       uint32_t new_alloc_len = sizeof(struct lttng_filter_bytecode_alloc) + new_len;
-       uint32_t old_alloc_len = (*fb)->alloc_len;
-
-       if (new_len > LTTNG_FILTER_MAX_LEN)
-               return -EINVAL;
-
-       if (new_alloc_len > old_alloc_len) {
-               struct lttng_filter_bytecode_alloc *newptr;
-
-               new_alloc_len =
-                       max_t(uint32_t, 1U << get_count_order(new_alloc_len), old_alloc_len << 1);
-               newptr = realloc(*fb, new_alloc_len);
-               if (!newptr)
-                       return -ENOMEM;
-               *fb = newptr;
-               /* We zero directly the memory from start of allocation. */
-               memset(&((char *) *fb)[old_alloc_len], 0, new_alloc_len - old_alloc_len);
-               (*fb)->alloc_len = new_alloc_len;
-       }
-       (*fb)->b.len += padding;
-       ret = (*fb)->b.len;
-       (*fb)->b.len += len;
-       return ret;
-}
-
-static
-int bytecode_push(struct lttng_filter_bytecode_alloc **fb, const void *data,
-               uint32_t align, uint32_t len)
-{
-       int32_t offset;
-
-       offset = bytecode_reserve(fb, align, len);
-       if (offset < 0)
-               return offset;
-       memcpy(&(*fb)->b.data[offset], data, len);
-       return 0;
-}
-
-static
-int bytecode_push_logical(struct lttng_filter_bytecode_alloc **fb,
-               struct logical_op *data,
-               uint32_t align, uint32_t len,
-               uint16_t *skip_offset)
-{
-       int32_t offset;
-
-       offset = bytecode_reserve(fb, align, len);
-       if (offset < 0)
-               return offset;
-       memcpy(&(*fb)->b.data[offset], data, len);
-       *skip_offset =
-               (void *) &((struct logical_op *) &(*fb)->b.data[offset])->skip_offset
-                       - (void *) &(*fb)->b.data[0];
-       return 0;
-}
-
-static
-int bytecode_patch(struct lttng_filter_bytecode_alloc **fb,
+int bytecode_patch(struct lttng_bytecode_alloc **fb,
                const void *data,
                uint16_t offset,
                uint32_t len)
@@ -143,7 +53,7 @@ int visit_node_root(struct filter_parser_ctx *ctx, struct ir_op *node)
                return ret;
 
        /* Generate end of bytecode instruction */
-       insn.op = FILTER_OP_RETURN;
+       insn.op = BYTECODE_OP_RETURN;
        return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
 }
 
@@ -175,7 +85,7 @@ int append_str(char **s, const char *append)
  */
 static
 int load_expression_legacy_match(const struct ir_load_expression *exp,
-               enum filter_op *op_type,
+               enum bytecode_op *op_type,
                char **symbol)
 {
        const struct ir_load_expression_op *op;
@@ -184,21 +94,21 @@ int load_expression_legacy_match(const struct ir_load_expression *exp,
        op = exp->child;
        switch (op->type) {
        case IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT:
-               *op_type = FILTER_OP_GET_CONTEXT_REF;
+               *op_type = BYTECODE_OP_GET_CONTEXT_REF;
                if (append_str(symbol, "$ctx.")) {
                        return -ENOMEM;
                }
                need_dot = false;
                break;
        case IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT:
-               *op_type = FILTER_OP_GET_CONTEXT_REF;
+               *op_type = BYTECODE_OP_GET_CONTEXT_REF;
                if (append_str(symbol, "$app.")) {
                        return -ENOMEM;
                }
                need_dot = false;
                break;
        case IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT:
-               *op_type = FILTER_OP_LOAD_FIELD_REF;
+               *op_type = BYTECODE_OP_LOAD_FIELD_REF;
                need_dot = false;
                break;
 
@@ -250,7 +160,7 @@ int visit_node_load_expression_legacy(struct filter_parser_ctx *ctx,
        struct field_ref ref_offset;
        uint32_t reloc_offset_u32;
        uint16_t reloc_offset;
-       enum filter_op op_type;
+       enum bytecode_op op_type;
        char *symbol = NULL;
        int ret;
 
@@ -328,100 +238,37 @@ int visit_node_load_expression(struct filter_parser_ctx *ctx,
                switch (op->type) {
                case IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT:
                {
-                       struct load_op *insn;
-                       uint32_t insn_len = sizeof(struct load_op);
-                       int ret;
-
-                       insn = calloc(insn_len, 1);
-                       if (!insn)
-                               return -ENOMEM;
-                       insn->op = FILTER_OP_GET_CONTEXT_ROOT;
-                       ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
-                       free(insn);
+                       int ret = bytecode_push_get_context_root(&ctx->bytecode);
                        if (ret) {
                                return ret;
                        }
+
                        break;
                }
                case IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT:
                {
-                       struct load_op *insn;
-                       uint32_t insn_len = sizeof(struct load_op);
-                       int ret;
-
-                       insn = calloc(insn_len, 1);
-                       if (!insn)
-                               return -ENOMEM;
-                       insn->op = FILTER_OP_GET_APP_CONTEXT_ROOT;
-                       ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
-                       free(insn);
+                       int ret = bytecode_push_get_app_context_root(&ctx->bytecode);
                        if (ret) {
                                return ret;
                        }
+
                        break;
                }
                case IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT:
                {
-                       struct load_op *insn;
-                       uint32_t insn_len = sizeof(struct load_op);
-                       int ret;
-
-                       insn = calloc(insn_len, 1);
-                       if (!insn)
-                               return -ENOMEM;
-                       insn->op = FILTER_OP_GET_PAYLOAD_ROOT;
-                       ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
-                       free(insn);
+                       int ret = bytecode_push_get_payload_root(&ctx->bytecode);
                        if (ret) {
                                return ret;
                        }
+
                        break;
                }
                case IR_LOAD_EXPRESSION_GET_SYMBOL:
                {
-                       struct load_op *insn;
-                       uint32_t insn_len = sizeof(struct load_op)
-                               + sizeof(struct get_symbol);
-                       struct get_symbol symbol_offset;
-                       uint32_t reloc_offset_u32;
-                       uint16_t reloc_offset;
-                       uint32_t bytecode_reloc_offset_u32;
-                       int ret;
-
-                       insn = calloc(insn_len, 1);
-                       if (!insn)
-                               return -ENOMEM;
-                       insn->op = FILTER_OP_GET_SYMBOL;
-                       bytecode_reloc_offset_u32 =
-                                       bytecode_get_len(&ctx->bytecode_reloc->b)
-                                       + sizeof(reloc_offset);
-                       symbol_offset.offset =
-                                       (uint16_t) bytecode_reloc_offset_u32;
-                       memcpy(insn->data, &symbol_offset,
-                                       sizeof(symbol_offset));
-                       /* reloc_offset points to struct load_op */
-                       reloc_offset_u32 = bytecode_get_len(&ctx->bytecode->b);
-                       if (reloc_offset_u32 > LTTNG_FILTER_MAX_LEN - 1) {
-                               free(insn);
-                               return -EINVAL;
-                       }
-                       reloc_offset = (uint16_t) reloc_offset_u32;
-                       ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
-                       if (ret) {
-                               free(insn);
-                               return ret;
-                       }
-                       /* append reloc */
-                       ret = bytecode_push(&ctx->bytecode_reloc, &reloc_offset,
-                                       1, sizeof(reloc_offset));
-                       if (ret) {
-                               free(insn);
-                               return ret;
-                       }
-                       ret = bytecode_push(&ctx->bytecode_reloc,
-                                       op->u.symbol,
-                                       1, strlen(op->u.symbol) + 1);
-                       free(insn);
+                       int ret = bytecode_push_get_symbol(
+                                       &ctx->bytecode,
+                                       &ctx->bytecode_reloc,
+                                       op->u.symbol);
                        if (ret) {
                                return ret;
                        }
@@ -429,20 +276,7 @@ int visit_node_load_expression(struct filter_parser_ctx *ctx,
                }
                case IR_LOAD_EXPRESSION_GET_INDEX:
                {
-                       struct load_op *insn;
-                       uint32_t insn_len = sizeof(struct load_op)
-                               + sizeof(struct get_index_u64);
-                       struct get_index_u64 index;
-                       int ret;
-
-                       insn = calloc(insn_len, 1);
-                       if (!insn)
-                               return -ENOMEM;
-                       insn->op = FILTER_OP_GET_INDEX_U64;
-                       index.index = op->u.index;
-                       memcpy(insn->data, &index, sizeof(index));
-                       ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
-                       free(insn);
+                       int ret = bytecode_push_get_index_u64(&ctx->bytecode, op->u.index);
                        if (ret) {
                                return ret;
                        }
@@ -457,7 +291,7 @@ int visit_node_load_expression(struct filter_parser_ctx *ctx,
                        insn = calloc(insn_len, 1);
                        if (!insn)
                                return -ENOMEM;
-                       insn->op = FILTER_OP_LOAD_FIELD;
+                       insn->op = BYTECODE_OP_LOAD_FIELD;
                        ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
                        free(insn);
                        if (ret) {
@@ -500,7 +334,7 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node)
                         * that the appropriate matching function can be
                         * called. Also, see comment below.
                         */
-                       insn->op = FILTER_OP_LOAD_STAR_GLOB_STRING;
+                       insn->op = BYTECODE_OP_LOAD_STAR_GLOB_STRING;
                        break;
                default:
                        /*
@@ -513,7 +347,7 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node)
                         * can be anywhere in the string) is a special
                         * case.
                         */
-                       insn->op = FILTER_OP_LOAD_STRING;
+                       insn->op = BYTECODE_OP_LOAD_STRING;
                        break;
                }
 
@@ -531,7 +365,7 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node)
                insn = calloc(insn_len, 1);
                if (!insn)
                        return -ENOMEM;
-               insn->op = FILTER_OP_LOAD_S64;
+               insn->op = BYTECODE_OP_LOAD_S64;
                memcpy(insn->data, &node->u.load.u.num, sizeof(int64_t));
                ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
                free(insn);
@@ -546,7 +380,7 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node)
                insn = calloc(insn_len, 1);
                if (!insn)
                        return -ENOMEM;
-               insn->op = FILTER_OP_LOAD_DOUBLE;
+               insn->op = BYTECODE_OP_LOAD_DOUBLE;
                memcpy(insn->data, &node->u.load.u.flt, sizeof(double));
                ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
                free(insn);
@@ -579,13 +413,13 @@ int visit_node_unary(struct filter_parser_ctx *ctx, struct ir_op *node)
                /* Nothing to do. */
                return 0;
        case AST_UNARY_MINUS:
-               insn.op = FILTER_OP_UNARY_MINUS;
+               insn.op = BYTECODE_OP_UNARY_MINUS;
                return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
        case AST_UNARY_NOT:
-               insn.op = FILTER_OP_UNARY_NOT;
+               insn.op = BYTECODE_OP_UNARY_NOT;
                return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
        case AST_UNARY_BIT_NOT:
-               insn.op = FILTER_OP_UNARY_BIT_NOT;
+               insn.op = BYTECODE_OP_UNARY_BIT_NOT;
                return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
        }
 }
@@ -622,53 +456,53 @@ int visit_node_binary(struct filter_parser_ctx *ctx, struct ir_op *node)
                return -EINVAL;
 
        case AST_OP_MUL:
-               insn.op = FILTER_OP_MUL;
+               insn.op = BYTECODE_OP_MUL;
                break;
        case AST_OP_DIV:
-               insn.op = FILTER_OP_DIV;
+               insn.op = BYTECODE_OP_DIV;
                break;
        case AST_OP_MOD:
-               insn.op = FILTER_OP_MOD;
+               insn.op = BYTECODE_OP_MOD;
                break;
        case AST_OP_PLUS:
-               insn.op = FILTER_OP_PLUS;
+               insn.op = BYTECODE_OP_PLUS;
                break;
        case AST_OP_MINUS:
-               insn.op = FILTER_OP_MINUS;
+               insn.op = BYTECODE_OP_MINUS;
                break;
        case AST_OP_BIT_RSHIFT:
-               insn.op = FILTER_OP_BIT_RSHIFT;
+               insn.op = BYTECODE_OP_BIT_RSHIFT;
                break;
        case AST_OP_BIT_LSHIFT:
-               insn.op = FILTER_OP_BIT_LSHIFT;
+               insn.op = BYTECODE_OP_BIT_LSHIFT;
                break;
        case AST_OP_BIT_AND:
-               insn.op = FILTER_OP_BIT_AND;
+               insn.op = BYTECODE_OP_BIT_AND;
                break;
        case AST_OP_BIT_OR:
-               insn.op = FILTER_OP_BIT_OR;
+               insn.op = BYTECODE_OP_BIT_OR;
                break;
        case AST_OP_BIT_XOR:
-               insn.op = FILTER_OP_BIT_XOR;
+               insn.op = BYTECODE_OP_BIT_XOR;
                break;
 
        case AST_OP_EQ:
-               insn.op = FILTER_OP_EQ;
+               insn.op = BYTECODE_OP_EQ;
                break;
        case AST_OP_NE:
-               insn.op = FILTER_OP_NE;
+               insn.op = BYTECODE_OP_NE;
                break;
        case AST_OP_GT:
-               insn.op = FILTER_OP_GT;
+               insn.op = BYTECODE_OP_GT;
                break;
        case AST_OP_LT:
-               insn.op = FILTER_OP_LT;
+               insn.op = BYTECODE_OP_LT;
                break;
        case AST_OP_GE:
-               insn.op = FILTER_OP_GE;
+               insn.op = BYTECODE_OP_GE;
                break;
        case AST_OP_LE:
-               insn.op = FILTER_OP_LE;
+               insn.op = BYTECODE_OP_LE;
                break;
        }
        return bytecode_push(&ctx->bytecode, &insn, 1, sizeof(insn));
@@ -699,9 +533,9 @@ int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node)
                if (node->u.binary.left->data_type == IR_DATA_FIELD_REF
                                || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF
                                || node->u.binary.left->data_type == IR_DATA_EXPRESSION) {
-                       cast_insn.op = FILTER_OP_CAST_TO_S64;
+                       cast_insn.op = BYTECODE_OP_CAST_TO_S64;
                } else {
-                       cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64;
+                       cast_insn.op = BYTECODE_OP_CAST_DOUBLE_TO_S64;
                }
                ret = bytecode_push(&ctx->bytecode, &cast_insn,
                                        1, sizeof(cast_insn));
@@ -715,10 +549,10 @@ int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node)
                return -EINVAL;
 
        case AST_OP_AND:
-               insn.op = FILTER_OP_AND;
+               insn.op = BYTECODE_OP_AND;
                break;
        case AST_OP_OR:
-               insn.op = FILTER_OP_OR;
+               insn.op = BYTECODE_OP_OR;
                break;
        }
        insn.skip_offset = (uint16_t) -1UL;     /* Temporary */
@@ -740,9 +574,9 @@ int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node)
                if (node->u.binary.right->data_type == IR_DATA_FIELD_REF
                                || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF
                                || node->u.binary.right->data_type == IR_DATA_EXPRESSION) {
-                       cast_insn.op = FILTER_OP_CAST_TO_S64;
+                       cast_insn.op = BYTECODE_OP_CAST_TO_S64;
                } else {
-                       cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64;
+                       cast_insn.op = BYTECODE_OP_CAST_DOUBLE_TO_S64;
                }
                ret = bytecode_push(&ctx->bytecode, &cast_insn,
                                        1, sizeof(cast_insn));
This page took 0.044796 seconds and 5 git commands to generate.