X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Flib%2Flttng-ctl%2Ffilter%2Ffilter-visitor-generate-bytecode.c;h=00c9adc16addaeb0a45d50f65551ec60ff745cd5;hp=98f837548f97a4afd9e40b3d50723ed27fb91cd5;hb=f19ca95ed68f6e3eff925676bc1d9bc8939c3ef2;hpb=5ddb0a08c5c3ca917b025032b864d78e53c7c68a diff --git a/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c b/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c index 98f837548..00c9adc16 100644 --- a/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c +++ b/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c @@ -22,16 +22,18 @@ #include #include #include -#include "align.h" +#include + #include "filter-bytecode.h" #include "filter-ir.h" #include "filter-ast.h" +#include + #ifndef max_t #define max_t(type, a, b) ((type) ((a) > (b) ? (a) : (b))) #endif -//#define INIT_ALLOC_SIZE PAGE_SIZE #define INIT_ALLOC_SIZE 4 static @@ -80,11 +82,14 @@ static inline int get_count_order(unsigned int count) static int bytecode_init(struct lttng_filter_bytecode_alloc **fb) { - *fb = calloc(sizeof(struct lttng_filter_bytecode_alloc) + INIT_ALLOC_SIZE, 1); + 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 = INIT_ALLOC_SIZE; + (*fb)->alloc_len = alloc_len; return 0; } } @@ -94,21 +99,25 @@ int32_t bytecode_reserve(struct lttng_filter_bytecode_alloc **fb, uint32_t align { 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 ((*fb)->b.len + padding + len > LTTNG_FILTER_MAX_LEN) + if (new_len > LTTNG_FILTER_MAX_LEN) return -EINVAL; - if ((*fb)->b.len + padding + len > (*fb)->alloc_len) { - uint32_t new_len = - max_t(uint32_t, 1U << get_count_order((*fb)->b.len + padding + len), - (*fb)->alloc_len << 1); - uint32_t old_len = (*fb)->alloc_len; + if (new_alloc_len > old_alloc_len) { + struct lttng_filter_bytecode_alloc *newptr; - *fb = realloc(*fb, sizeof(struct lttng_filter_bytecode_alloc) + new_len); - if (!*fb) + 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; - memset(&(*fb)->b.data[old_len], 0, new_len - old_len); - (*fb)->alloc_len = new_len; + *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; @@ -213,7 +222,7 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node) if (!insn) return -ENOMEM; insn->op = FILTER_OP_LOAD_S64; - *(int64_t *) insn->data = node->u.load.u.num; + memcpy(insn->data, &node->u.load.u.num, sizeof(int64_t)); ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len); free(insn); return ret; @@ -228,27 +237,44 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node) if (!insn) return -ENOMEM; insn->op = FILTER_OP_LOAD_DOUBLE; - *(double *) insn->data = node->u.load.u.flt; + memcpy(insn->data, &node->u.load.u.flt, sizeof(double)); ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len); free(insn); return ret; } - case IR_DATA_FIELD_REF: + case IR_DATA_FIELD_REF: /* fall-through */ + case IR_DATA_GET_CONTEXT_REF: { struct load_op *insn; uint32_t insn_len = sizeof(struct load_op) + sizeof(struct field_ref); struct field_ref ref_offset; + uint32_t reloc_offset_u32; uint16_t reloc_offset; insn = calloc(insn_len, 1); if (!insn) return -ENOMEM; - insn->op = FILTER_OP_LOAD_FIELD_REF; + switch(node->data_type) { + case IR_DATA_FIELD_REF: + insn->op = FILTER_OP_LOAD_FIELD_REF; + break; + case IR_DATA_GET_CONTEXT_REF: + insn->op = FILTER_OP_GET_CONTEXT_REF; + break; + default: + free(insn); + return -EINVAL; + } ref_offset.offset = (uint16_t) -1U; memcpy(insn->data, &ref_offset, sizeof(ref_offset)); /* reloc_offset points to struct load_op */ - reloc_offset = bytecode_get_len(&ctx->bytecode->b); + 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); @@ -399,11 +425,13 @@ int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node) if (ret) return ret; /* Cast to s64 if float or field ref */ - if (node->u.binary.left->data_type == IR_DATA_FIELD_REF + 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_FLOAT) { struct cast_op cast_insn; - if (node->u.binary.left->data_type == IR_DATA_FIELD_REF) { + if (node->u.binary.left->data_type == IR_DATA_FIELD_REF + || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF) { cast_insn.op = FILTER_OP_CAST_TO_S64; } else { cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64; @@ -436,11 +464,13 @@ int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node) if (ret) return ret; /* Cast to s64 if float or field ref */ - if (node->u.binary.right->data_type == IR_DATA_FIELD_REF + 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_FLOAT) { struct cast_op cast_insn; - if (node->u.binary.right->data_type == IR_DATA_FIELD_REF) { + if (node->u.binary.right->data_type == IR_DATA_FIELD_REF + || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF) { cast_insn.op = FILTER_OP_CAST_TO_S64; } else { cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64; @@ -487,16 +517,25 @@ int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx, } } -__attribute__((visibility("hidden"))) +LTTNG_HIDDEN void filter_bytecode_free(struct filter_parser_ctx *ctx) { - free(ctx->bytecode); - ctx->bytecode = NULL; - free(ctx->bytecode_reloc); - ctx->bytecode_reloc = NULL; + if (!ctx) { + return; + } + + if (ctx->bytecode) { + free(ctx->bytecode); + ctx->bytecode = NULL; + } + + if (ctx->bytecode_reloc) { + free(ctx->bytecode_reloc); + ctx->bytecode_reloc = NULL; + } } -__attribute__((visibility("hidden"))) +LTTNG_HIDDEN int filter_visitor_bytecode_generate(struct filter_parser_ctx *ctx) { int ret;