callstack context: use delimiter when stack is incomplete
[lttng-modules.git] / lttng-filter-validator.c
index cc8f45962c73f51c7a0c944579df6675a447aba0..a4ca777563fa9ca13e85281500b1f3db17de4d4f 100644 (file)
@@ -303,6 +303,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode,
        }
 
        case FILTER_OP_RETURN:
+       case FILTER_OP_RETURN_S64:
        {
                if (unlikely(pc + sizeof(struct return_op)
                                > start_pc + bytecode->len)) {
@@ -317,8 +318,6 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode,
        case FILTER_OP_MOD:
        case FILTER_OP_PLUS:
        case FILTER_OP_MINUS:
-       case FILTER_OP_RSHIFT:
-       case FILTER_OP_LSHIFT:
        case FILTER_OP_EQ_DOUBLE:
        case FILTER_OP_NE_DOUBLE:
        case FILTER_OP_GT_DOUBLE:
@@ -372,6 +371,8 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode,
        case FILTER_OP_LT_S64:
        case FILTER_OP_GE_S64:
        case FILTER_OP_LE_S64:
+       case FILTER_OP_BIT_RSHIFT:
+       case FILTER_OP_BIT_LSHIFT:
        case FILTER_OP_BIT_AND:
        case FILTER_OP_BIT_OR:
        case FILTER_OP_BIT_XOR:
@@ -390,6 +391,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode,
        case FILTER_OP_UNARY_PLUS_S64:
        case FILTER_OP_UNARY_MINUS_S64:
        case FILTER_OP_UNARY_NOT_S64:
+       case FILTER_OP_UNARY_BIT_NOT:
        {
                if (unlikely(pc + sizeof(struct unary_op)
                                > start_pc + bytecode->len)) {
@@ -512,6 +514,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode,
                if (unlikely(pc + sizeof(struct load_op) + sizeof(struct get_symbol)
                                > start_pc + bytecode->len)) {
                        ret = -ERANGE;
+                       break;
                }
                ret = validate_get_symbol(bytecode, sym);
                break;
@@ -585,6 +588,7 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
        }
 
        case FILTER_OP_RETURN:
+       case FILTER_OP_RETURN_S64:
        {
                goto end;
        }
@@ -595,8 +599,6 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
        case FILTER_OP_MOD:
        case FILTER_OP_PLUS:
        case FILTER_OP_MINUS:
-       case FILTER_OP_RSHIFT:
-       case FILTER_OP_LSHIFT:
        /* Floating point */
        case FILTER_OP_EQ_DOUBLE:
        case FILTER_OP_NE_DOUBLE:
@@ -733,6 +735,16 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                break;
        }
 
+       case FILTER_OP_BIT_RSHIFT:
+               ret = bin_op_bitwise_check(stack, opcode, ">>");
+               if (ret < 0)
+                       goto end;
+               break;
+       case FILTER_OP_BIT_LSHIFT:
+               ret = bin_op_bitwise_check(stack, opcode, "<<");
+               if (ret < 0)
+                       goto end;
+               break;
        case FILTER_OP_BIT_AND:
                ret = bin_op_bitwise_check(stack, opcode, "&");
                if (ret < 0)
@@ -777,6 +789,32 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                }
                break;
        }
+       case FILTER_OP_UNARY_BIT_NOT:
+       {
+               if (!vstack_ax(stack)) {
+                       printk(KERN_WARNING "Empty stack\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               switch (vstack_ax(stack)->type) {
+               default:
+                       printk(KERN_WARNING "unknown register type\n");
+                       ret = -EINVAL;
+                       goto end;
+
+               case REG_STRING:
+               case REG_STAR_GLOB_STRING:
+               case REG_DOUBLE:
+                       printk(KERN_WARNING "Unary bitwise op can only be applied to numeric registers\n");
+                       ret = -EINVAL;
+                       goto end;
+               case REG_S64:
+                       break;
+               case REG_TYPE_UNKNOWN:
+                       break;
+               }
+               break;
+       }
 
        case FILTER_OP_UNARY_PLUS_S64:
        case FILTER_OP_UNARY_MINUS_S64:
@@ -1148,14 +1186,34 @@ int exec_insn(struct bytecode_runtime *bytecode,
                goto end;
        }
 
+       case FILTER_OP_RETURN_S64:
+       {
+               if (!vstack_ax(stack)) {
+                       printk(KERN_WARNING "Empty stack\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               switch (vstack_ax(stack)->type) {
+               case REG_S64:
+                       break;
+               default:
+               case REG_TYPE_UNKNOWN:
+                       printk(KERN_WARNING "Unexpected register type %d at end of bytecode\n",
+                               (int) vstack_ax(stack)->type);
+                       ret = -EINVAL;
+                       goto end;
+               }
+
+               ret = 0;
+               goto end;
+       }
+
        /* binary */
        case FILTER_OP_MUL:
        case FILTER_OP_DIV:
        case FILTER_OP_MOD:
        case FILTER_OP_PLUS:
        case FILTER_OP_MINUS:
-       case FILTER_OP_RSHIFT:
-       case FILTER_OP_LSHIFT:
        /* Floating point */
        case FILTER_OP_EQ_DOUBLE:
        case FILTER_OP_NE_DOUBLE:
@@ -1209,6 +1267,8 @@ int exec_insn(struct bytecode_runtime *bytecode,
        case FILTER_OP_LT_S64:
        case FILTER_OP_GE_S64:
        case FILTER_OP_LE_S64:
+       case FILTER_OP_BIT_RSHIFT:
+       case FILTER_OP_BIT_LSHIFT:
        case FILTER_OP_BIT_AND:
        case FILTER_OP_BIT_OR:
        case FILTER_OP_BIT_XOR:
@@ -1317,6 +1377,31 @@ int exec_insn(struct bytecode_runtime *bytecode,
                break;
        }
 
+       case FILTER_OP_UNARY_BIT_NOT:
+       {
+               /* Pop 1, push 1 */
+               if (!vstack_ax(stack)) {
+                       printk(KERN_WARNING "Empty stack\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               switch (vstack_ax(stack)->type) {
+               case REG_S64:
+               case REG_TYPE_UNKNOWN:
+                       break;
+               case REG_DOUBLE:
+               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 unary_op);
+               break;
+       }
+
        /* logical */
        case FILTER_OP_AND:
        case FILTER_OP_OR:
This page took 0.026459 seconds and 4 git commands to generate.