bytecode: add `REG_U64` interpreter register type
[lttng-modules.git] / src / lttng-filter-validator.c
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.026514 seconds and 4 git commands to generate.