X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Ffilter%2Ffilter-visitor-generate-bytecode.c;h=458b9d042e73cd60a40f469c40c5793554f93ff4;hp=699273c3d984f7e9aba6f4ee51b0d77e2fa666d1;hb=2463b7879c00298daa79744cdaae82ac061a4ed8;hpb=3a4595c2469472dee1656cde5f8882c2123efd3c diff --git a/src/common/filter/filter-visitor-generate-bytecode.c b/src/common/filter/filter-visitor-generate-bytecode.c index 699273c3d..458b9d042 100644 --- a/src/common/filter/filter-visitor-generate-bytecode.c +++ b/src/common/filter/filter-visitor-generate-bytecode.c @@ -12,114 +12,24 @@ #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 +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));