X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Ffilter%2Ffilter-visitor-generate-bytecode.c;h=fe1220305f943897e0bae20bde720a2999132db2;hb=ca806b0b247f89c62ac628a7779ae84049a8c2d7;hp=699273c3d984f7e9aba6f4ee51b0d77e2fa666d1;hpb=e4d2f27a74baf6942ac8fcafd5ea53e775ceceb3;p=lttng-tools.git diff --git a/src/common/filter/filter-visitor-generate-bytecode.c b/src/common/filter/filter-visitor-generate-bytecode.c index 699273c3d..fe1220305 100644 --- a/src/common/filter/filter-visitor-generate-bytecode.c +++ b/src/common/filter/filter-visitor-generate-bytecode.c @@ -11,115 +11,27 @@ #include #include -#include #include +#include #include -#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 +#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 +55,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 +87,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 +96,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 +162,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,136 +240,66 @@ 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; + ret = bytecode_push_get_context_root(&ctx->bytecode); - 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); 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; + ret = bytecode_push_get_app_context_root( + &ctx->bytecode); - 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); 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; + ret = bytecode_push_get_payload_root(&ctx->bytecode); - 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); 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; + ret = bytecode_push_get_symbol(&ctx->bytecode, + &ctx->bytecode_reloc, op->u.symbol); - 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); if (ret) { return ret; } + break; } 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; + ret = bytecode_push_get_index_u64( + &ctx->bytecode, op->u.index); - 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); if (ret) { return ret; } + break; } case IR_LOAD_EXPRESSION_LOAD_FIELD: { 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_LOAD_FIELD; + insn->op = BYTECODE_OP_LOAD_FIELD; ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len); free(insn); if (ret) { @@ -500,7 +342,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 +355,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 +373,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 +388,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 +421,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 +464,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 +541,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 +557,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 +582,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)); @@ -786,7 +628,6 @@ int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx, } } -LTTNG_HIDDEN void filter_bytecode_free(struct filter_parser_ctx *ctx) { if (!ctx) { @@ -804,7 +645,6 @@ void filter_bytecode_free(struct filter_parser_ctx *ctx) } } -LTTNG_HIDDEN int filter_visitor_bytecode_generate(struct filter_parser_ctx *ctx) { int ret;