X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-filter-interpreter.c;h=29bcaeffa0656cacea08f59f5c6b782bb23c1af7;hb=f6df8626c40e58c39e83215a5bdbdf7a29038c35;hp=e6e96dbff9a9bf53cdb346b68cd63a9b4728d457;hpb=9b33aac411033000adafce04f947c7aca892c342;p=lttng-ust.git diff --git a/liblttng-ust/lttng-filter-interpreter.c b/liblttng-ust/lttng-filter-interpreter.c index e6e96dbf..29bcaeff 100644 --- a/liblttng-ust/lttng-filter-interpreter.c +++ b/liblttng-ust/lttng-filter-interpreter.c @@ -59,18 +59,28 @@ int stack_strcmp(struct estack *stack, int top, const char *cmp_type) int escaped_r0 = 0; if (unlikely(p - estack_bx(stack, top)->u.s.str > estack_bx(stack, top)->u.s.seq_len || *p == '\0')) { - if (q - estack_ax(stack, top)->u.s.str > estack_ax(stack, top)->u.s.seq_len || *q == '\0') - diff = 0; - else - diff = -1; - break; + if (q - estack_ax(stack, top)->u.s.str > estack_ax(stack, top)->u.s.seq_len || *q == '\0') { + return 0; + } else { + if (estack_ax(stack, top)->u.s.literal) { + ret = parse_char(&q); + if (ret == -1) + return 0; + } + return -1; + } } if (unlikely(q - estack_ax(stack, top)->u.s.str > estack_ax(stack, top)->u.s.seq_len || *q == '\0')) { - if (p - estack_bx(stack, top)->u.s.str > estack_bx(stack, top)->u.s.seq_len || *p == '\0') - diff = 0; - else - diff = 1; - break; + if (p - estack_bx(stack, top)->u.s.str > estack_bx(stack, top)->u.s.seq_len || *p == '\0') { + return 0; + } else { + if (estack_bx(stack, top)->u.s.literal) { + ret = parse_char(&p); + if (ret == -1) + return 0; + } + return 1; + } } if (estack_bx(stack, top)->u.s.literal) { ret = parse_char(&p); @@ -105,7 +115,7 @@ int stack_strcmp(struct estack *stack, int top, const char *cmp_type) return diff; } -int lttng_filter_false(void *filter_data, +uint64_t lttng_filter_false(void *filter_data, const char *filter_stack_data) { return 0; @@ -157,13 +167,18 @@ LABEL_##name #endif -int lttng_filter_interpret_bytecode(void *filter_data, +/* + * Return 0 (discard), or raise the 0x1 flag (log event). + * Currently, other flags are kept for future extensions and have no + * effect. + */ +uint64_t lttng_filter_interpret_bytecode(void *filter_data, const char *filter_stack_data) { struct bytecode_runtime *bytecode = filter_data; void *pc, *next_pc, *start_pc; int ret = -EINVAL; - int retval = 0; + uint64_t retval = 0; struct estack _stack; struct estack *stack = &_stack; register int64_t ax = 0, bx = 0; @@ -248,13 +263,14 @@ int lttng_filter_interpret_bytecode(void *filter_data, [ FILTER_OP_AND ] = &&LABEL_FILTER_OP_AND, [ FILTER_OP_OR ] = &&LABEL_FILTER_OP_OR, - /* load */ + /* load field ref */ [ FILTER_OP_LOAD_FIELD_REF ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF, [ FILTER_OP_LOAD_FIELD_REF_STRING ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING, [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE, [ FILTER_OP_LOAD_FIELD_REF_S64 ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64, [ FILTER_OP_LOAD_FIELD_REF_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE, + /* load from immediate operand */ [ FILTER_OP_LOAD_STRING ] = &&LABEL_FILTER_OP_LOAD_STRING, [ FILTER_OP_LOAD_S64 ] = &&LABEL_FILTER_OP_LOAD_S64, [ FILTER_OP_LOAD_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_DOUBLE, @@ -263,6 +279,12 @@ int lttng_filter_interpret_bytecode(void *filter_data, [ FILTER_OP_CAST_TO_S64 ] = &&LABEL_FILTER_OP_CAST_TO_S64, [ FILTER_OP_CAST_DOUBLE_TO_S64 ] = &&LABEL_FILTER_OP_CAST_DOUBLE_TO_S64, [ FILTER_OP_CAST_NOP ] = &&LABEL_FILTER_OP_CAST_NOP, + + /* get context ref */ + [ FILTER_OP_GET_CONTEXT_REF ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF, + [ FILTER_OP_GET_CONTEXT_REF_STRING ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_STRING, + [ FILTER_OP_GET_CONTEXT_REF_S64 ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_S64, + [ FILTER_OP_GET_CONTEXT_REF_DOUBLE ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_DOUBLE, }; #endif /* #ifndef INTERPRETER_USE_SWITCH */ @@ -270,6 +292,7 @@ int lttng_filter_interpret_bytecode(void *filter_data, OP(FILTER_OP_UNKNOWN): OP(FILTER_OP_LOAD_FIELD_REF): + OP(FILTER_OP_GET_CONTEXT_REF): #ifdef INTERPRETER_USE_SWITCH default: #endif /* INTERPRETER_USE_SWITCH */ @@ -279,6 +302,7 @@ int lttng_filter_interpret_bytecode(void *filter_data, goto end; OP(FILTER_OP_RETURN): + /* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */ retval = !!estack_ax_v; ret = 0; goto end; @@ -694,7 +718,7 @@ int lttng_filter_interpret_bytecode(void *filter_data, } - /* load */ + /* load field ref */ OP(FILTER_OP_LOAD_FIELD_REF_STRING): { struct load_op *insn = (struct load_op *) pc; @@ -770,6 +794,7 @@ int lttng_filter_interpret_bytecode(void *filter_data, PO; } + /* load from immediate operand */ OP(FILTER_OP_LOAD_STRING): { struct load_op *insn = (struct load_op *) pc; @@ -828,6 +853,68 @@ int lttng_filter_interpret_bytecode(void *filter_data, PO; } + /* get context ref */ + OP(FILTER_OP_GET_CONTEXT_REF_STRING): + { + struct load_op *insn = (struct load_op *) pc; + struct field_ref *ref = (struct field_ref *) insn->data; + struct lttng_ctx_field *ctx_field; + union lttng_ctx_value v; + + dbg_printf("get context ref offset %u type string\n", + ref->offset); + ctx_field = <tng_static_ctx->fields[ref->offset]; + ctx_field->get_value(ctx_field, &v); + estack_push(stack, top, ax, bx); + estack_ax(stack, top)->u.s.str = v.str; + if (unlikely(!estack_ax(stack, top)->u.s.str)) { + dbg_printf("Filter warning: loading a NULL string.\n"); + ret = -EINVAL; + goto end; + } + estack_ax(stack, top)->u.s.seq_len = UINT_MAX; + estack_ax(stack, top)->u.s.literal = 0; + dbg_printf("ref get context string %s\n", estack_ax(stack, top)->u.s.str); + next_pc += sizeof(struct load_op) + sizeof(struct field_ref); + PO; + } + + OP(FILTER_OP_GET_CONTEXT_REF_S64): + { + struct load_op *insn = (struct load_op *) pc; + struct field_ref *ref = (struct field_ref *) insn->data; + struct lttng_ctx_field *ctx_field; + union lttng_ctx_value v; + + dbg_printf("get context ref offset %u type s64\n", + ref->offset); + ctx_field = <tng_static_ctx->fields[ref->offset]; + ctx_field->get_value(ctx_field, &v); + estack_push(stack, top, ax, bx); + estack_ax_v = v.s64; + dbg_printf("ref get context s64 %" PRIi64 "\n", estack_ax_v); + next_pc += sizeof(struct load_op) + sizeof(struct field_ref); + PO; + } + + OP(FILTER_OP_GET_CONTEXT_REF_DOUBLE): + { + struct load_op *insn = (struct load_op *) pc; + struct field_ref *ref = (struct field_ref *) insn->data; + struct lttng_ctx_field *ctx_field; + union lttng_ctx_value v; + + dbg_printf("get context ref offset %u type double\n", + ref->offset); + ctx_field = <tng_static_ctx->fields[ref->offset]; + ctx_field->get_value(ctx_field, &v); + estack_push(stack, top, ax, bx); + memcpy(&estack_ax(stack, top)->u.d, &v.d, sizeof(struct literal_double)); + dbg_printf("ref get context double %g\n", estack_ax(stack, top)->u.d); + next_pc += sizeof(struct load_op) + sizeof(struct field_ref); + PO; + } + END_OP end: /* return 0 (discard) on error */