bytecode: set register type to `REG_PTR` even if not used
[lttng-modules.git] / src / lttng-filter-interpreter.c
index 09302c76145d5fdacdffc713bcecd6a3815ed8c3..69db94940d961604f51cae2091a37441cc883ab7 100644 (file)
@@ -15,8 +15,6 @@
 #include <lttng/filter.h>
 #include <lttng/string-utils.h>
 
-LTTNG_STACK_FRAME_NON_STANDARD(lttng_filter_interpret_bytecode);
-
 /*
  * get_char should be called with page fault handler disabled if it is expected
  * to handle user-space read.
@@ -209,7 +207,7 @@ int stack_strcmp(struct estack *stack, int top, const char *cmp_type)
        return diff;
 }
 
-uint64_t lttng_filter_false(void *filter_data,
+uint64_t lttng_filter_interpret_bytecode_false(void *filter_data,
                struct lttng_probe_ctx *lttng_probe_ctx,
                const char *filter_stack_data)
 {
@@ -262,6 +260,9 @@ LABEL_##name
 
 #endif
 
+#define IS_INTEGER_REGISTER(reg_type) \
+               (reg_type == REG_S64 || reg_type == REG_U64)
+
 static int context_get_index(struct lttng_probe_ctx *lttng_probe_ctx,
                struct load_ptr *ptr,
                uint32_t idx)
@@ -358,13 +359,6 @@ static int dynamic_get_index(struct lttng_probe_ctx *lttng_probe_ctx,
        int ret;
        const struct filter_get_index_data *gid;
 
-       /*
-        * Types nested within variants need to perform dynamic lookup
-        * based on the field descriptions. LTTng-UST does not implement
-        * variants for now.
-        */
-       if (stack_top->u.ptr.field)
-               return -EINVAL;
        gid = (const struct filter_get_index_data *) &runtime->data[index];
        switch (stack_top->u.ptr.type) {
        case LOAD_OBJECT:
@@ -380,7 +374,7 @@ static int dynamic_get_index(struct lttng_probe_ctx *lttng_probe_ctx,
                        stack_top->u.ptr.ptr = ptr;
                        stack_top->u.ptr.object_type = gid->elem.type;
                        stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
-                       /* field is only used for types nested within variants. */
+                       BUG_ON(stack_top->u.ptr.field->type.atype != atype_array_nestable);
                        stack_top->u.ptr.field = NULL;
                        break;
                }
@@ -399,7 +393,7 @@ static int dynamic_get_index(struct lttng_probe_ctx *lttng_probe_ctx,
                        stack_top->u.ptr.ptr = ptr;
                        stack_top->u.ptr.object_type = gid->elem.type;
                        stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
-                       /* field is only used for types nested within variants. */
+                       BUG_ON(stack_top->u.ptr.field->type.atype != atype_sequence_nestable);
                        stack_top->u.ptr.field = NULL;
                        break;
                }
@@ -432,10 +426,12 @@ static int dynamic_get_index(struct lttng_probe_ctx *lttng_probe_ctx,
                        stack_top->u.ptr.ptr = *(const char * const *) stack_top->u.ptr.ptr;
                stack_top->u.ptr.object_type = gid->elem.type;
                stack_top->u.ptr.type = LOAD_OBJECT;
-               /* field is only used for types nested within variants. */
-               stack_top->u.ptr.field = NULL;
+               stack_top->u.ptr.field = gid->field;
                break;
        }
+
+       stack_top->type = REG_PTR;
+
        return 0;
 
 end:
@@ -461,6 +457,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
        case OBJECT_TYPE_S8:
                dbg_printk("op load field s8\n");
                stack_top->u.v = *(int8_t *) stack_top->u.ptr.ptr;
+               stack_top->type = REG_S64;
                break;
        case OBJECT_TYPE_S16:
        {
@@ -471,6 +468,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                if (stack_top->u.ptr.rev_bo)
                        __swab16s(&tmp);
                stack_top->u.v = tmp;
+               stack_top->type = REG_S64;
                break;
        }
        case OBJECT_TYPE_S32:
@@ -482,6 +480,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                if (stack_top->u.ptr.rev_bo)
                        __swab32s(&tmp);
                stack_top->u.v = tmp;
+               stack_top->type = REG_S64;
                break;
        }
        case OBJECT_TYPE_S64:
@@ -493,11 +492,13 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                if (stack_top->u.ptr.rev_bo)
                        __swab64s(&tmp);
                stack_top->u.v = tmp;
+               stack_top->type = REG_S64;
                break;
        }
        case OBJECT_TYPE_U8:
                dbg_printk("op load field u8\n");
                stack_top->u.v = *(uint8_t *) stack_top->u.ptr.ptr;
+               stack_top->type = REG_U64;
                break;
        case OBJECT_TYPE_U16:
        {
@@ -508,6 +509,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                if (stack_top->u.ptr.rev_bo)
                        __swab16s(&tmp);
                stack_top->u.v = tmp;
+               stack_top->type = REG_U64;
                break;
        }
        case OBJECT_TYPE_U32:
@@ -519,6 +521,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                if (stack_top->u.ptr.rev_bo)
                        __swab32s(&tmp);
                stack_top->u.v = tmp;
+               stack_top->type = REG_U64;
                break;
        }
        case OBJECT_TYPE_U64:
@@ -530,6 +533,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                if (stack_top->u.ptr.rev_bo)
                        __swab64s(&tmp);
                stack_top->u.v = tmp;
+               stack_top->type = REG_U64;
                break;
        }
        case OBJECT_TYPE_STRING:
@@ -547,6 +551,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                stack_top->u.s.seq_len = LTTNG_SIZE_MAX;
                stack_top->u.s.literal_type =
                        ESTACK_STRING_LITERAL_TYPE_NONE;
+               stack_top->type = REG_STRING;
                break;
        }
        case OBJECT_TYPE_STRING_SEQUENCE:
@@ -564,6 +569,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                }
                stack_top->u.s.literal_type =
                        ESTACK_STRING_LITERAL_TYPE_NONE;
+               stack_top->type = REG_STRING;
                break;
        }
        case OBJECT_TYPE_DYNAMIC:
@@ -590,22 +596,93 @@ end:
        return ret;
 }
 
+static
+int lttng_bytecode_interpret_format_output(struct estack_entry *ax,
+               struct lttng_interpreter_output *output)
+{
+       int ret;
+
+again:
+       switch (ax->type) {
+       case REG_S64:
+               output->type = LTTNG_INTERPRETER_TYPE_S64;
+               output->u.s = ax->u.v;
+               break;
+       case REG_U64:
+               output->type = LTTNG_INTERPRETER_TYPE_U64;
+               output->u.u = (uint64_t) ax->u.v;
+               break;
+       case REG_STRING:
+               output->type = LTTNG_INTERPRETER_TYPE_STRING;
+               output->u.str.str = ax->u.s.str;
+               output->u.str.len = ax->u.s.seq_len;
+               break;
+       case REG_PTR:
+               switch (ax->u.ptr.object_type) {
+               case OBJECT_TYPE_S8:
+               case OBJECT_TYPE_S16:
+               case OBJECT_TYPE_S32:
+               case OBJECT_TYPE_S64:
+               case OBJECT_TYPE_U8:
+               case OBJECT_TYPE_U16:
+               case OBJECT_TYPE_U32:
+               case OBJECT_TYPE_U64:
+               case OBJECT_TYPE_DOUBLE:
+               case OBJECT_TYPE_STRING:
+               case OBJECT_TYPE_STRING_SEQUENCE:
+                       ret = dynamic_load_field(ax);
+                       if (ret)
+                               return ret;
+                       /* Retry after loading ptr into stack top. */
+                       goto again;
+               case OBJECT_TYPE_SEQUENCE:
+                       output->type = LTTNG_INTERPRETER_TYPE_SEQUENCE;
+                       output->u.sequence.ptr = *(const char **) (ax->u.ptr.ptr + sizeof(unsigned long));
+                       output->u.sequence.nr_elem = *(unsigned long *) ax->u.ptr.ptr;
+                       output->u.sequence.nested_type = ax->u.ptr.field->type.u.sequence_nestable.elem_type;
+                       break;
+               case OBJECT_TYPE_ARRAY:
+                       /* Skip count (unsigned long) */
+                       output->type = LTTNG_INTERPRETER_TYPE_SEQUENCE;
+                       output->u.sequence.ptr = *(const char **) (ax->u.ptr.ptr + sizeof(unsigned long));
+                       output->u.sequence.nr_elem = ax->u.ptr.field->type.u.array_nestable.length;
+                       output->u.sequence.nested_type = ax->u.ptr.field->type.u.array_nestable.elem_type;
+                       break;
+               case OBJECT_TYPE_STRUCT:
+               case OBJECT_TYPE_VARIANT:
+               default:
+                       return -EINVAL;
+               }
+
+               break;
+       case REG_STAR_GLOB_STRING:
+       case REG_TYPE_UNKNOWN:
+       default:
+               return -EINVAL;
+       }
+
+       return LTTNG_FILTER_RECORD_FLAG;
+}
+
 /*
  * 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,
+static
+uint64_t bytecode_interpret(void *interpreter_data,
                struct lttng_probe_ctx *lttng_probe_ctx,
-               const char *filter_stack_data)
+               const char *interpreter_stack_data,
+               struct lttng_interpreter_output *output)
 {
-       struct bytecode_runtime *bytecode = filter_data;
+       struct bytecode_runtime *bytecode = interpreter_data;
        void *pc, *next_pc, *start_pc;
        int ret = -EINVAL;
        uint64_t retval = 0;
        struct estack _stack;
        struct estack *stack = &_stack;
        register int64_t ax = 0, bx = 0;
+       register enum entry_type ax_t = REG_TYPE_UNKNOWN, bx_t = REG_TYPE_UNKNOWN;
        register int top = FILTER_STACK_EMPTY;
 #ifndef INTERPRETER_USE_SWITCH
        static void *dispatch[NR_FILTER_OPS] = {
@@ -764,7 +841,25 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                OP(FILTER_OP_RETURN):
                OP(FILTER_OP_RETURN_S64):
                        /* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */
-                       retval = !!estack_ax_v;
+                       switch (estack_ax_t) {
+                       case REG_S64:
+                       case REG_U64:
+                               retval = !!estack_ax_v;
+                               break;
+                       case REG_DOUBLE:
+                       case REG_STRING:
+                       case REG_PTR:
+                               if (!output) {
+                                       ret = -EINVAL;
+                                       goto end;
+                               }
+                               retval = 0;
+                               break;
+                       case REG_STAR_GLOB_STRING:
+                       case REG_TYPE_UNKNOWN:
+                               ret = -EINVAL;
+                               goto end;
+                       }
                        ret = 0;
                        goto end;
 
@@ -795,8 +890,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (stack_strcmp(stack, top, "==") == 0);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -805,8 +901,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (stack_strcmp(stack, top, "!=") != 0);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -815,8 +912,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (stack_strcmp(stack, top, ">") > 0);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -825,8 +923,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (stack_strcmp(stack, top, "<") < 0);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -835,8 +934,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (stack_strcmp(stack, top, ">=") >= 0);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -845,8 +945,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (stack_strcmp(stack, top, "<=") <= 0);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -856,8 +957,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (stack_star_glob_match(stack, top, "==") == 0);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -866,8 +968,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (stack_star_glob_match(stack, top, "!=") != 0);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -877,8 +980,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (estack_bx_v == estack_ax_v);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -887,8 +991,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (estack_bx_v != estack_ax_v);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -897,8 +1002,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (estack_bx_v > estack_ax_v);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -907,8 +1013,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (estack_bx_v < estack_ax_v);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -917,8 +1024,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (estack_bx_v >= estack_ax_v);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -927,8 +1035,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        int res;
 
                        res = (estack_bx_v <= estack_ax_v);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -965,14 +1074,20 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                {
                        int64_t res;
 
+                       if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
+                               ret = -EINVAL;
+                               goto end;
+                       }
+
                        /* Catch undefined behavior. */
                        if (unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
                                ret = -EINVAL;
                                goto end;
                        }
                        res = ((uint64_t) estack_bx_v >> (uint32_t) estack_ax_v);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_U64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -980,14 +1095,20 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                {
                        int64_t res;
 
+                       if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
+                               ret = -EINVAL;
+                               goto end;
+                       }
+
                        /* Catch undefined behavior. */
                        if (unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
                                ret = -EINVAL;
                                goto end;
                        }
                        res = ((uint64_t) estack_bx_v << (uint32_t) estack_ax_v);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_U64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -995,9 +1116,15 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                {
                        int64_t res;
 
+                       if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
+                               ret = -EINVAL;
+                               goto end;
+                       }
+
                        res = ((uint64_t) estack_bx_v & (uint64_t) estack_ax_v);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_U64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -1005,9 +1132,15 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                {
                        int64_t res;
 
+                       if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
+                               ret = -EINVAL;
+                               goto end;
+                       }
+
                        res = ((uint64_t) estack_bx_v | (uint64_t) estack_ax_v);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_U64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -1015,9 +1148,15 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                {
                        int64_t res;
 
+                       if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
+                               ret = -EINVAL;
+                               goto end;
+                       }
+
                        res = ((uint64_t) estack_bx_v ^ (uint64_t) estack_ax_v);
-                       estack_pop(stack, top, ax, bx);
+                       estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
+                       estack_ax_t = REG_U64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -1035,6 +1174,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                OP(FILTER_OP_UNARY_BIT_NOT):
                {
                        estack_ax_v = ~(uint64_t) estack_ax_v;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct unary_op);
                        PO;
                }
@@ -1047,6 +1187,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                OP(FILTER_OP_UNARY_MINUS_S64):
                {
                        estack_ax_v = -estack_ax_v;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct unary_op);
                        PO;
                }
@@ -1059,6 +1200,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                OP(FILTER_OP_UNARY_NOT_S64):
                {
                        estack_ax_v = !estack_ax_v;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct unary_op);
                        PO;
                }
@@ -1080,7 +1222,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                                next_pc = start_pc + insn->skip_offset;
                        } else {
                                /* Pop 1 when jump not taken */
-                               estack_pop(stack, top, ax, bx);
+                               estack_pop(stack, top, ax, bx, ax_t, bx_t);
                                next_pc += sizeof(struct logical_op);
                        }
                        PO;
@@ -1098,7 +1240,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                                next_pc = start_pc + insn->skip_offset;
                        } else {
                                /* Pop 1 when jump not taken */
-                               estack_pop(stack, top, ax, bx);
+                               estack_pop(stack, top, ax, bx, ax_t, bx_t);
                                next_pc += sizeof(struct logical_op);
                        }
                        PO;
@@ -1113,9 +1255,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
 
                        dbg_printk("load field ref offset %u type string\n",
                                ref->offset);
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax(stack, top)->u.s.str =
-                               *(const char * const *) &filter_stack_data[ref->offset];
+                               *(const char * const *) &interpreter_stack_data[ref->offset];
                        if (unlikely(!estack_ax(stack, top)->u.s.str)) {
                                dbg_printk("Filter warning: loading a NULL string.\n");
                                ret = -EINVAL;
@@ -1125,6 +1267,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        estack_ax(stack, top)->u.s.literal_type =
                                ESTACK_STRING_LITERAL_TYPE_NONE;
                        estack_ax(stack, top)->u.s.user = 0;
+                       estack_ax(stack, top)->type = REG_STRING;
                        dbg_printk("ref load string %s\n", estack_ax(stack, top)->u.s.str);
                        next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
                        PO;
@@ -1137,11 +1280,11 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
 
                        dbg_printk("load field ref offset %u type sequence\n",
                                ref->offset);
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax(stack, top)->u.s.seq_len =
-                               *(unsigned long *) &filter_stack_data[ref->offset];
+                               *(unsigned long *) &interpreter_stack_data[ref->offset];
                        estack_ax(stack, top)->u.s.str =
-                               *(const char **) (&filter_stack_data[ref->offset
+                               *(const char **) (&interpreter_stack_data[ref->offset
                                                                + sizeof(unsigned long)]);
                        if (unlikely(!estack_ax(stack, top)->u.s.str)) {
                                dbg_printk("Filter warning: loading a NULL sequence.\n");
@@ -1162,9 +1305,10 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
 
                        dbg_printk("load field ref offset %u type s64\n",
                                ref->offset);
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v =
-                               ((struct literal_numeric *) &filter_stack_data[ref->offset])->v;
+                               ((struct literal_numeric *) &interpreter_stack_data[ref->offset])->v;
+                       estack_ax_t = REG_S64;
                        dbg_printk("ref load s64 %lld\n",
                                (long long) estack_ax_v);
                        next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
@@ -1183,7 +1327,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        struct load_op *insn = (struct load_op *) pc;
 
                        dbg_printk("load string %s\n", insn->data);
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax(stack, top)->u.s.str = insn->data;
                        estack_ax(stack, top)->u.s.seq_len = LTTNG_SIZE_MAX;
                        estack_ax(stack, top)->u.s.literal_type =
@@ -1198,7 +1342,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        struct load_op *insn = (struct load_op *) pc;
 
                        dbg_printk("load globbing pattern %s\n", insn->data);
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax(stack, top)->u.s.str = insn->data;
                        estack_ax(stack, top)->u.s.seq_len = LTTNG_SIZE_MAX;
                        estack_ax(stack, top)->u.s.literal_type =
@@ -1212,8 +1356,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                {
                        struct load_op *insn = (struct load_op *) pc;
 
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = ((struct literal_numeric *) insn->data)->v;
+                       estack_ax_t = REG_S64;
                        dbg_printk("load s64 %lld\n",
                                (long long) estack_ax_v);
                        next_pc += sizeof(struct load_op)
@@ -1258,7 +1403,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                                ref->offset);
                        ctx_field = &lttng_static_ctx->fields[ref->offset];
                        ctx_field->get_value(ctx_field, lttng_probe_ctx, &v);
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax(stack, top)->u.s.str = v.str;
                        if (unlikely(!estack_ax(stack, top)->u.s.str)) {
                                dbg_printk("Filter warning: loading a NULL string.\n");
@@ -1269,6 +1414,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        estack_ax(stack, top)->u.s.literal_type =
                                ESTACK_STRING_LITERAL_TYPE_NONE;
                        estack_ax(stack, top)->u.s.user = 0;
+                       estack_ax(stack, top)->type = REG_STRING;
                        dbg_printk("ref get context string %s\n", estack_ax(stack, top)->u.s.str);
                        next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
                        PO;
@@ -1285,8 +1431,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                                ref->offset);
                        ctx_field = &lttng_static_ctx->fields[ref->offset];
                        ctx_field->get_value(ctx_field, lttng_probe_ctx, &v);
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = v.s64;
+                       estack_ax_t = REG_S64;
                        dbg_printk("ref get context s64 %lld\n",
                                (long long) estack_ax_v);
                        next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
@@ -1307,9 +1454,9 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
 
                        dbg_printk("load field ref offset %u type user string\n",
                                ref->offset);
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax(stack, top)->u.s.user_str =
-                               *(const char * const *) &filter_stack_data[ref->offset];
+                               *(const char * const *) &interpreter_stack_data[ref->offset];
                        if (unlikely(!estack_ax(stack, top)->u.s.str)) {
                                dbg_printk("Filter warning: loading a NULL string.\n");
                                ret = -EINVAL;
@@ -1319,6 +1466,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        estack_ax(stack, top)->u.s.literal_type =
                                ESTACK_STRING_LITERAL_TYPE_NONE;
                        estack_ax(stack, top)->u.s.user = 1;
+                       estack_ax(stack, top)->type = REG_STRING;
                        dbg_printk("ref load string %s\n", estack_ax(stack, top)->u.s.str);
                        next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
                        PO;
@@ -1331,11 +1479,11 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
 
                        dbg_printk("load field ref offset %u type user sequence\n",
                                ref->offset);
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax(stack, top)->u.s.seq_len =
-                               *(unsigned long *) &filter_stack_data[ref->offset];
+                               *(unsigned long *) &interpreter_stack_data[ref->offset];
                        estack_ax(stack, top)->u.s.user_str =
-                               *(const char **) (&filter_stack_data[ref->offset
+                               *(const char **) (&interpreter_stack_data[ref->offset
                                                                + sizeof(unsigned long)]);
                        if (unlikely(!estack_ax(stack, top)->u.s.str)) {
                                dbg_printk("Filter warning: loading a NULL sequence.\n");
@@ -1352,10 +1500,11 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                OP(FILTER_OP_GET_CONTEXT_ROOT):
                {
                        dbg_printk("op get context root\n");
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_CONTEXT;
                        /* "field" only needed for variants. */
                        estack_ax(stack, top)->u.ptr.field = NULL;
+                       estack_ax(stack, top)->type = REG_PTR;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1369,11 +1518,12 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                OP(FILTER_OP_GET_PAYLOAD_ROOT):
                {
                        dbg_printk("op get app payload root\n");
-                       estack_push(stack, top, ax, bx);
+                       estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_PAYLOAD;
-                       estack_ax(stack, top)->u.ptr.ptr = filter_stack_data;
+                       estack_ax(stack, top)->u.ptr.ptr = interpreter_stack_data;
                        /* "field" only needed for variants. */
                        estack_ax(stack, top)->u.ptr.field = NULL;
+                       estack_ax(stack, top)->type = REG_PTR;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1420,6 +1570,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        if (ret)
                                goto end;
                        estack_ax_v = estack_ax(stack, top)->u.v;
+                       estack_ax_t = estack_ax(stack, top)->type;
                        next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
                        PO;
                }
@@ -1434,6 +1585,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        if (ret)
                                goto end;
                        estack_ax_v = estack_ax(stack, top)->u.v;
+                       estack_ax_t = estack_ax(stack, top)->type;
                        next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
                        PO;
                }
@@ -1445,6 +1597,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        if (ret)
                                goto end;
                        estack_ax_v = estack_ax(stack, top)->u.v;
+                       estack_ax_t = estack_ax(stack, top)->type;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1454,6 +1607,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        dbg_printk("op load field s8\n");
 
                        estack_ax_v = *(int8_t *) estack_ax(stack, top)->u.ptr.ptr;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1462,6 +1616,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        dbg_printk("op load field s16\n");
 
                        estack_ax_v = *(int16_t *) estack_ax(stack, top)->u.ptr.ptr;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1470,6 +1625,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        dbg_printk("op load field s32\n");
 
                        estack_ax_v = *(int32_t *) estack_ax(stack, top)->u.ptr.ptr;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1478,6 +1634,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        dbg_printk("op load field s64\n");
 
                        estack_ax_v = *(int64_t *) estack_ax(stack, top)->u.ptr.ptr;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1486,6 +1643,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        dbg_printk("op load field u8\n");
 
                        estack_ax_v = *(uint8_t *) estack_ax(stack, top)->u.ptr.ptr;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1494,6 +1652,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        dbg_printk("op load field u16\n");
 
                        estack_ax_v = *(uint16_t *) estack_ax(stack, top)->u.ptr.ptr;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1502,6 +1661,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        dbg_printk("op load field u32\n");
 
                        estack_ax_v = *(uint32_t *) estack_ax(stack, top)->u.ptr.ptr;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1510,6 +1670,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        dbg_printk("op load field u64\n");
 
                        estack_ax_v = *(uint64_t *) estack_ax(stack, top)->u.ptr.ptr;
+                       estack_ax_t = REG_S64;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1534,6 +1695,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        estack_ax(stack, top)->u.s.seq_len = LTTNG_SIZE_MAX;
                        estack_ax(stack, top)->u.s.literal_type =
                                ESTACK_STRING_LITERAL_TYPE_NONE;
+                       estack_ax(stack, top)->type = REG_STRING;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1553,6 +1715,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        }
                        estack_ax(stack, top)->u.s.literal_type =
                                ESTACK_STRING_LITERAL_TYPE_NONE;
+                       estack_ax(stack, top)->type = REG_STRING;
                        next_pc += sizeof(struct load_op);
                        PO;
                }
@@ -1562,8 +1725,23 @@ end:
        /* Return _DISCARD on error. */
        if (ret)
                return LTTNG_FILTER_DISCARD;
+
+       if (output) {
+               return lttng_bytecode_interpret_format_output(
+                               estack_ax(stack, top), output);
+       }
+
        return retval;
 }
+LTTNG_STACK_FRAME_NON_STANDARD(bytecode_interpret);
+
+uint64_t lttng_filter_interpret_bytecode(void *filter_data,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               const char *filter_stack_data)
+{
+       return bytecode_interpret(filter_data, lttng_probe_ctx,
+                       filter_stack_data, NULL);
+}
 
 #undef START_OP
 #undef OP
This page took 0.03631 seconds and 4 git commands to generate.