X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Flib%2Flttng-ctl%2Ffilter%2Ffilter-visitor-generate-bytecode.c;h=74cef91dc3c0c35acb9ce7b167afc05b3a71286a;hp=7d62757477febbcddd0a88e8f4524d74c74682a9;hb=661dfdd190c65bad5a044e21c1d5f9ad59144bf8;hpb=3f0c88379cfbbbec84641e13b21f290a563f8729 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 7d6275747..74cef91dc 100644 --- a/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c +++ b/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c @@ -22,7 +22,9 @@ #include #include #include -#include "align.h" +#include +#include + #include "filter-bytecode.h" #include "filter-ir.h" #include "filter-ast.h" @@ -33,47 +35,17 @@ #define max_t(type, a, b) ((type) ((a) > (b) ? (a) : (b))) #endif -//#define INIT_ALLOC_SIZE PAGE_SIZE #define INIT_ALLOC_SIZE 4 static int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx, struct ir_op *node); -static inline int fls(unsigned int x) -{ - int r = 32; - - if (!x) - return 0; - if (!(x & 0xFFFF0000U)) { - x <<= 16; - r -= 16; - } - if (!(x & 0xFF000000U)) { - x <<= 8; - r -= 8; - } - if (!(x & 0xF0000000U)) { - x <<= 4; - r -= 4; - } - if (!(x & 0xC0000000U)) { - x <<= 2; - r -= 2; - } - if (!(x & 0x80000000U)) { - x <<= 1; - r -= 1; - } - return r; -} - static inline int get_count_order(unsigned int count) { int order; - order = fls(count) - 1; + order = lttng_fls(count) - 1; if (count & (count - 1)) order++; return order; @@ -201,13 +173,38 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node) { struct load_op *insn; uint32_t insn_len = sizeof(struct load_op) - + strlen(node->u.load.u.string) + 1; + + strlen(node->u.load.u.string.value) + 1; insn = calloc(insn_len, 1); if (!insn) return -ENOMEM; - insn->op = FILTER_OP_LOAD_STRING; - strcpy(insn->data, node->u.load.u.string); + + switch (node->u.load.u.string.type) { + case IR_LOAD_STRING_TYPE_GLOB_STAR: + /* + * We explicitly tell the interpreter here that + * this load is a full star globbing pattern so + * that the appropriate matching function can be + * called. Also, see comment below. + */ + insn->op = FILTER_OP_LOAD_STAR_GLOB_STRING; + break; + default: + /* + * This is the "legacy" string, which includes + * star globbing patterns with a star only at + * the end. Both "plain" and "star at the end" + * literal strings are handled at the same place + * by the tracer's filter bytecode interpreter, + * whereas full star globbing patterns (stars + * can be anywhere in the string) is a special + * case. + */ + insn->op = FILTER_OP_LOAD_STRING; + break; + } + + strcpy(insn->data, node->u.load.u.string.value); ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len); free(insn); return ret; @@ -255,7 +252,7 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node) insn = calloc(insn_len, 1); if (!insn) return -ENOMEM; - switch(node->data_type) { + switch (node->data_type) { case IR_DATA_FIELD_REF: insn->op = FILTER_OP_LOAD_FIELD_REF; break; @@ -292,6 +289,57 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node) free(insn); return ret; } + case IR_DATA_FIELD_REF_INDEX: /* fall-through */ + case IR_DATA_GET_CONTEXT_REF_INDEX: + { + struct load_op *insn; + uint32_t insn_len = sizeof(struct load_op) + + sizeof(struct field_ref_index); + struct field_ref_index ref_index_offset; + uint32_t reloc_offset_u32; + uint16_t reloc_offset; + + insn = calloc(insn_len, 1); + if (!insn) + return -ENOMEM; + switch (node->data_type) { + case IR_DATA_FIELD_REF_INDEX: + insn->op = FILTER_OP_LOAD_FIELD_REF_INDEX; + break; + case IR_DATA_GET_CONTEXT_REF_INDEX: + insn->op = FILTER_OP_GET_CONTEXT_REF_INDEX; + break; + default: + free(insn); + return -EINVAL; + } + ref_index_offset.offset = (uint16_t) -1U; + ref_index_offset.index = node->u.load.u.ref_index.index; + memcpy(insn->data, &ref_index_offset, sizeof(ref_index_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, node->u.load.u.ref_index.symbol, + 1, strlen(node->u.load.u.ref_index.symbol) + 1); + free(insn); + return ret; + } } } @@ -426,12 +474,16 @@ int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node) return ret; /* Cast to s64 if float or 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_GET_CONTEXT_REF + || node->u.binary.left->data_type == IR_DATA_FIELD_REF_INDEX + || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF_INDEX) || 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 - || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF) { + || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF + || node->u.binary.left->data_type == IR_DATA_FIELD_REF_INDEX + || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF_INDEX) { cast_insn.op = FILTER_OP_CAST_TO_S64; } else { cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64; @@ -465,12 +517,16 @@ int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node) return ret; /* Cast to s64 if float or 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_GET_CONTEXT_REF + || node->u.binary.right->data_type == IR_DATA_FIELD_REF_INDEX + || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF_INDEX) || 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 - || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF) { + || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF + || node->u.binary.right->data_type == IR_DATA_FIELD_REF_INDEX + || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF_INDEX) { cast_insn.op = FILTER_OP_CAST_TO_S64; } else { cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64; @@ -520,6 +576,10 @@ int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx, LTTNG_HIDDEN void filter_bytecode_free(struct filter_parser_ctx *ctx) { + if (!ctx) { + return; + } + if (ctx->bytecode) { free(ctx->bytecode); ctx->bytecode = NULL;