bytecode: add `REG_U64` interpreter register type
authorFrancis Deslauriers <francis.deslauriers@efficios.com>
Thu, 30 Apr 2020 21:30:45 +0000 (17:30 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 25 Nov 2020 18:02:41 +0000 (13:02 -0500)
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I53c12a54cbd416617834982bbd2b7cf528d41a76

include/lttng/filter.h
src/lttng-filter-interpreter.c
src/lttng-filter-specialize.c
src/lttng-filter-validator.c

index ce26921386ce38eae0a46b0aa0130d382cdab4e1..26538b5e932957382e3344349ec6f7ade0bddddf 100644 (file)
@@ -47,6 +47,7 @@ struct bytecode_runtime {
 
 enum entry_type {
        REG_S64,
+       REG_U64,
        REG_DOUBLE,
        REG_STRING,
        REG_STAR_GLOB_STRING,
index 4aefb04ed50a43ed10b895091c5001c7cb59e4b5..7c05c24f97786127fbdd8fffc94ae83fcbcd8c80 100644 (file)
@@ -262,7 +262,8 @@ LABEL_##name
 
 #endif
 
-#define IS_INTEGER_REGISTER(reg_type) (reg_type == REG_S64)
+#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,
@@ -504,7 +505,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
        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_S64;
+               stack_top->type = REG_U64;
                break;
        case OBJECT_TYPE_U16:
        {
@@ -515,7 +516,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;
+               stack_top->type = REG_U64;
                break;
        }
        case OBJECT_TYPE_U32:
@@ -527,7 +528,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;
+               stack_top->type = REG_U64;
                break;
        }
        case OBJECT_TYPE_U64:
@@ -539,7 +540,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_S64;
+               stack_top->type = REG_U64;
                break;
        }
        case OBJECT_TYPE_STRING:
@@ -779,6 +780,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        /* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */
                        switch (estack_ax_t) {
                        case REG_S64:
+                       case REG_U64:
                                retval = !!estack_ax_v;
                                break;
                        case REG_DOUBLE:
@@ -1016,7 +1018,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        res = ((uint64_t) estack_bx_v >> (uint32_t) estack_ax_v);
                        estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
-                       estack_ax_t = REG_S64;
+                       estack_ax_t = REG_U64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -1037,7 +1039,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        res = ((uint64_t) estack_bx_v << (uint32_t) estack_ax_v);
                        estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
-                       estack_ax_t = REG_S64;
+                       estack_ax_t = REG_U64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -1053,7 +1055,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        res = ((uint64_t) estack_bx_v & (uint64_t) estack_ax_v);
                        estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
-                       estack_ax_t = REG_S64;
+                       estack_ax_t = REG_U64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -1069,7 +1071,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        res = ((uint64_t) estack_bx_v | (uint64_t) estack_ax_v);
                        estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
-                       estack_ax_t = REG_S64;
+                       estack_ax_t = REG_U64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
@@ -1085,7 +1087,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        res = ((uint64_t) estack_bx_v ^ (uint64_t) estack_ax_v);
                        estack_pop(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = res;
-                       estack_ax_t = REG_S64;
+                       estack_ax_t = REG_U64;
                        next_pc += sizeof(struct binary_op);
                        PO;
                }
index c7718ec726778fcf75b48e1d09314885f53265b5..82b5cb6400a785c7d8637e0674a8bba36d974c34 100644 (file)
@@ -313,9 +313,7 @@ static int specialize_load_object(const struct lttng_event_field *field,
                struct vstack_load *load, bool is_context)
 {
        load->type = LOAD_OBJECT;
-       /*
-        * LTTng-UST layout all integer fields as s64 on the stack for the filter.
-        */
+
        switch (field->type.atype) {
        case atype_integer:
                if (field->type.u.integer.signedness)
index 9057ee8a8c19d887b874436c4bd5a5cf9ee8c568..7e308281f26b7ffd5c8813d1a868bdeb7132ff08 100644 (file)
@@ -127,6 +127,7 @@ int bin_op_compare_check(struct vstack *stack, const filter_opcode_t opcode,
                        }
                        break;
                case REG_S64:
+               case REG_U64:
                        goto error_mismatch;
                }
                break;
@@ -144,10 +145,12 @@ int bin_op_compare_check(struct vstack *stack, const filter_opcode_t opcode,
                        break;
                case REG_STAR_GLOB_STRING:
                case REG_S64:
+               case REG_U64:
                        goto error_mismatch;
                }
                break;
        case REG_S64:
+       case REG_U64:
                switch (vstack_bx(stack)->type) {
                default:
                case REG_DOUBLE:
@@ -158,6 +161,7 @@ int bin_op_compare_check(struct vstack *stack, const filter_opcode_t opcode,
                case REG_STAR_GLOB_STRING:
                        goto error_mismatch;
                case REG_S64:
+               case REG_U64:
                        break;
                }
                break;
@@ -170,6 +174,7 @@ int bin_op_compare_check(struct vstack *stack, const filter_opcode_t opcode,
                case REG_STRING:
                case REG_STAR_GLOB_STRING:
                case REG_S64:
+               case REG_U64:
                        goto unknown;
                }
                break;
@@ -216,10 +221,12 @@ int bin_op_bitwise_check(struct vstack *stack, filter_opcode_t opcode,
                        goto error_type;
                case REG_TYPE_UNKNOWN:
                case REG_S64:
+               case REG_U64:
                        goto unknown;
                }
                break;
        case REG_S64:
+       case REG_U64:
                switch (vstack_bx(stack)->type) {
                default:
                case REG_DOUBLE:
@@ -227,6 +234,7 @@ int bin_op_bitwise_check(struct vstack *stack, filter_opcode_t opcode,
                case REG_TYPE_UNKNOWN:
                        goto unknown;
                case REG_S64:
+               case REG_U64:
                        break;
                }
                break;
@@ -707,8 +715,20 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                }
-               if (vstack_ax(stack)->type != REG_S64
-                               || vstack_bx(stack)->type != REG_S64) {
+               switch (vstack_ax(stack)->type) {
+               case REG_S64:
+               case REG_U64:
+                       break;
+               default:
+                       printk(KERN_WARNING "LTTng: filter: Unexpected register type for s64 comparator\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               switch (vstack_bx(stack)->type) {
+               case REG_S64:
+               case REG_U64:
+                       break;
+               default:
                        printk(KERN_WARNING "LTTng: filter: Unexpected register type for s64 comparator\n");
                        ret = -EINVAL;
                        goto end;
@@ -765,6 +785,7 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                case REG_S64:
+               case REG_U64:
                case REG_TYPE_UNKNOWN:
                        break;
                }
@@ -790,7 +811,7 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                case REG_S64:
-                       break;
+               case REG_U64:
                case REG_TYPE_UNKNOWN:
                        break;
                }
@@ -806,7 +827,8 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                }
-               if (vstack_ax(stack)->type != REG_S64) {
+               if (vstack_ax(stack)->type != REG_S64 &&
+                               vstack_ax(stack)->type != REG_U64) {
                        printk(KERN_WARNING "LTTng: filter: Invalid register type\n");
                        ret = -EINVAL;
                        goto end;
@@ -825,7 +847,8 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                }
-               if (vstack_ax(stack)->type != REG_S64) {
+               if (vstack_ax(stack)->type != REG_S64 &&
+                               vstack_ax(stack)->type != REG_U64) {
                        printk(KERN_WARNING "LTTng: filter: Logical comparator expects S64 register\n");
                        ret = -EINVAL;
                        goto end;
@@ -1154,6 +1177,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                case REG_TYPE_UNKNOWN:
                        break;
                default:
@@ -1176,6 +1200,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                        break;
                default:
                case REG_TYPE_UNKNOWN:
@@ -1248,6 +1273,36 @@ int exec_insn(struct bytecode_runtime *bytecode,
        case FILTER_OP_LT_S64:
        case FILTER_OP_GE_S64:
        case FILTER_OP_LE_S64:
+       {
+               /* Pop 2, push 1 */
+               if (vstack_pop(stack)) {
+                       ret = -EINVAL;
+                       goto end;
+               }
+               if (!vstack_ax(stack)) {
+                       printk(KERN_WARNING "Empty stack\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               switch (vstack_ax(stack)->type) {
+               case REG_S64:
+               case REG_U64:
+               case REG_DOUBLE:
+               case REG_STRING:
+               case REG_STAR_GLOB_STRING:
+               case REG_TYPE_UNKNOWN:
+                       break;
+               default:
+                       printk(KERN_WARNING "Unexpected register type %d for operation\n",
+                               (int) vstack_ax(stack)->type);
+                       ret = -EINVAL;
+                       goto end;
+               }
+
+               vstack_ax(stack)->type = REG_S64;
+               next_pc += sizeof(struct binary_op);
+               break;
+       }
        case FILTER_OP_BIT_RSHIFT:
        case FILTER_OP_BIT_LSHIFT:
        case FILTER_OP_BIT_AND:
@@ -1266,6 +1321,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                case REG_DOUBLE:
                case REG_STRING:
                case REG_STAR_GLOB_STRING:
@@ -1278,7 +1334,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                        goto end;
                }
 
-               vstack_ax(stack)->type = REG_S64;
+               vstack_ax(stack)->type = REG_U64;
                next_pc += sizeof(struct binary_op);
                break;
        }
@@ -1295,6 +1351,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                case REG_TYPE_UNKNOWN:
                        break;
                default:
@@ -1321,6 +1378,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                        break;
                default:
                        printk(KERN_WARNING "LTTng: filter: Unexpected register type %d for operation\n",
@@ -1329,7 +1387,6 @@ int exec_insn(struct bytecode_runtime *bytecode,
                        goto end;
                }
 
-               vstack_ax(stack)->type = REG_S64;
                next_pc += sizeof(struct unary_op);
                break;
        }
@@ -1344,6 +1401,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                case REG_TYPE_UNKNOWN:
                        break;
                default:
@@ -1353,7 +1411,6 @@ int exec_insn(struct bytecode_runtime *bytecode,
                        goto end;
                }
 
-               vstack_ax(stack)->type = REG_S64;
                next_pc += sizeof(struct unary_op);
                break;
        }
@@ -1368,6 +1425,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                case REG_TYPE_UNKNOWN:
                        break;
                case REG_DOUBLE:
@@ -1378,7 +1436,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                        goto end;
                }
 
-               vstack_ax(stack)->type = REG_S64;
+               vstack_ax(stack)->type = REG_U64;
                next_pc += sizeof(struct unary_op);
                break;
        }
@@ -1406,6 +1464,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                /* There is always a cast-to-s64 operation before a or/and op. */
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                        break;
                default:
                        printk(KERN_WARNING "LTTng: filter: Incorrect register type %d for operation\n",
@@ -1513,6 +1572,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                case REG_DOUBLE:
                case REG_TYPE_UNKNOWN:
                        break;
@@ -1570,6 +1630,22 @@ int exec_insn(struct bytecode_runtime *bytecode,
        case FILTER_OP_LOAD_FIELD_S16:
        case FILTER_OP_LOAD_FIELD_S32:
        case FILTER_OP_LOAD_FIELD_S64:
+       {
+               /* Pop 1, push 1 */
+               if (!vstack_ax(stack)) {
+                       printk(KERN_WARNING "Empty stack\n\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               if (vstack_ax(stack)->type != REG_PTR) {
+                       printk(KERN_WARNING "Expecting pointer on top of stack\n\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               vstack_ax(stack)->type = REG_S64;
+               next_pc += sizeof(struct load_op);
+               break;
+       }
        case FILTER_OP_LOAD_FIELD_U8:
        case FILTER_OP_LOAD_FIELD_U16:
        case FILTER_OP_LOAD_FIELD_U32:
@@ -1586,11 +1662,10 @@ int exec_insn(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                }
-               vstack_ax(stack)->type = REG_S64;
+               vstack_ax(stack)->type = REG_U64;
                next_pc += sizeof(struct load_op);
                break;
        }
-
        case FILTER_OP_LOAD_FIELD_STRING:
        case FILTER_OP_LOAD_FIELD_SEQUENCE:
        {
This page took 0.03315 seconds and 4 git commands to generate.