X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Flib%2Flttng-ctl%2Ffilter%2Ffilter-visitor-generate-bytecode.c;h=74cef91dc3c0c35acb9ce7b167afc05b3a71286a;hb=661dfdd190c65bad5a044e21c1d5f9ad59144bf8;hp=e28abd57271ecec91936d19e2918c8c1b1aa986c;hpb=afc5df0361caae100946d58aa557433891d52cb3;p=lttng-tools.git 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 e28abd572..74cef91dc 100644 --- a/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c +++ b/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c @@ -173,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; @@ -227,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; @@ -264,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; + } } } @@ -398,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; @@ -437,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;