Filter: add lshift, rshift, bit not ops
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 22 Sep 2017 00:42:34 +0000 (20:42 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 6 Jun 2018 20:42:04 +0000 (16:42 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
filter-bytecode.h
lttng-filter-interpreter.c
lttng-filter-specialize.c
lttng-filter-validator.c
lttng-filter.c

index 931daa9726c839da2c402b0da34a7604813b0ba0..2aa5c2d08462b6ca23129848b5ea8144d61c32f9 100644 (file)
@@ -72,8 +72,8 @@ enum filter_op {
        FILTER_OP_MOD                           = 4,
        FILTER_OP_PLUS                          = 5,
        FILTER_OP_MINUS                         = 6,
-       FILTER_OP_RSHIFT                        = 7,
-       FILTER_OP_LSHIFT                        = 8,
+       FILTER_OP_BIT_RSHIFT                    = 7,
+       FILTER_OP_BIT_LSHIFT                    = 8,
        FILTER_OP_BIT_AND                       = 9,
        FILTER_OP_BIT_OR                        = 10,
        FILTER_OP_BIT_XOR                       = 11,
@@ -202,6 +202,8 @@ enum filter_op {
        FILTER_OP_LOAD_FIELD_SEQUENCE           = 96,
        FILTER_OP_LOAD_FIELD_DOUBLE             = 97,
 
+       FILTER_OP_UNARY_BIT_NOT                 = 98,
+
        NR_FILTER_OPS,
 };
 
index 0bede9c5bb36c761583369850cba43eb0d92086d..5bf0bd6074719ef59cf5dc8a2fe57f4cc0f5e7e7 100644 (file)
@@ -647,8 +647,8 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                [ FILTER_OP_MOD ] = &&LABEL_FILTER_OP_MOD,
                [ FILTER_OP_PLUS ] = &&LABEL_FILTER_OP_PLUS,
                [ FILTER_OP_MINUS ] = &&LABEL_FILTER_OP_MINUS,
-               [ FILTER_OP_RSHIFT ] = &&LABEL_FILTER_OP_RSHIFT,
-               [ FILTER_OP_LSHIFT ] = &&LABEL_FILTER_OP_LSHIFT,
+               [ FILTER_OP_BIT_RSHIFT ] = &&LABEL_FILTER_OP_BIT_RSHIFT,
+               [ FILTER_OP_BIT_LSHIFT ] = &&LABEL_FILTER_OP_BIT_LSHIFT,
                [ FILTER_OP_BIT_AND ] = &&LABEL_FILTER_OP_BIT_AND,
                [ FILTER_OP_BIT_OR ] = &&LABEL_FILTER_OP_BIT_OR,
                [ FILTER_OP_BIT_XOR ] = &&LABEL_FILTER_OP_BIT_XOR,
@@ -769,6 +769,8 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                [ FILTER_OP_LOAD_FIELD_STRING ] = &&LABEL_FILTER_OP_LOAD_FIELD_STRING,
                [ FILTER_OP_LOAD_FIELD_SEQUENCE ] = &&LABEL_FILTER_OP_LOAD_FIELD_SEQUENCE,
                [ FILTER_OP_LOAD_FIELD_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_FIELD_DOUBLE,
+
+               [ FILTER_OP_UNARY_BIT_NOT ] = &&LABEL_FILTER_OP_UNARY_BIT_NOT,
        };
 #endif /* #ifndef INTERPRETER_USE_SWITCH */
 
@@ -797,8 +799,6 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                OP(FILTER_OP_MOD):
                OP(FILTER_OP_PLUS):
                OP(FILTER_OP_MINUS):
-               OP(FILTER_OP_RSHIFT):
-               OP(FILTER_OP_LSHIFT):
                        printk(KERN_WARNING "unsupported bytecode op %u\n",
                                (unsigned int) *(filter_opcode_t *) pc);
                        ret = -EINVAL;
@@ -986,6 +986,26 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        BUG_ON(1);
                        PO;
                }
+               OP(FILTER_OP_BIT_RSHIFT):
+               {
+                       int64_t res;
+
+                       res = (estack_bx_v >> estack_ax_v);
+                       estack_pop(stack, top, ax, bx);
+                       estack_ax_v = res;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+               OP(FILTER_OP_BIT_LSHIFT):
+               {
+                       int64_t res;
+
+                       res = (estack_bx_v << estack_ax_v);
+                       estack_pop(stack, top, ax, bx);
+                       estack_ax_v = res;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
                OP(FILTER_OP_BIT_AND):
                {
                        int64_t res;
@@ -1027,6 +1047,13 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        goto end;
 
 
+               OP(FILTER_OP_UNARY_BIT_NOT):
+               {
+                       estack_ax_v = ~estack_ax_v;
+                       next_pc += sizeof(struct unary_op);
+                       PO;
+               }
+
                OP(FILTER_OP_UNARY_PLUS_S64):
                {
                        next_pc += sizeof(struct unary_op);
index 7112b0ae0aa3ec3f75ddc48cdb08bb60ad8468f2..b9ddfb100225846e889e43b8eaa1cecf1f8bcb92 100644 (file)
@@ -527,8 +527,6 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                case FILTER_OP_MOD:
                case FILTER_OP_PLUS:
                case FILTER_OP_MINUS:
-               case FILTER_OP_RSHIFT:
-               case FILTER_OP_LSHIFT:
                        printk(KERN_WARNING "unsupported bytecode op %u\n",
                                (unsigned int) *(filter_opcode_t *) pc);
                        ret = -EINVAL;
@@ -804,6 +802,8 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                case FILTER_OP_LT_S64_DOUBLE:
                case FILTER_OP_GE_S64_DOUBLE:
                case FILTER_OP_LE_S64_DOUBLE:
+               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:
@@ -885,6 +885,13 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                        break;
                }
 
+               case FILTER_OP_UNARY_BIT_NOT:
+               {
+                       /* Pop 1, push 1 */
+                       next_pc += sizeof(struct unary_op);
+                       break;
+               }
+
                case FILTER_OP_UNARY_PLUS_S64:
                case FILTER_OP_UNARY_MINUS_S64:
                case FILTER_OP_UNARY_NOT_S64:
index cc8f45962c73f51c7a0c944579df6675a447aba0..c7b81bb6bbd193187434bd5f2b5f21a48f3fff7a 100644 (file)
@@ -317,8 +317,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 +370,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 +390,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)) {
@@ -595,8 +596,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 +732,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 +786,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:
@@ -1154,8 +1189,6 @@ int exec_insn(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:
@@ -1209,6 +1242,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 +1352,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:
index d7fcceae8d2ca214969bb4cbcdfd570adede0e7d..ff9767436fb7dec2ed4a082fc8c586183f505deb 100644 (file)
@@ -40,8 +40,8 @@ static const char *opnames[] = {
        [ FILTER_OP_MOD ] = "MOD",
        [ FILTER_OP_PLUS ] = "PLUS",
        [ FILTER_OP_MINUS ] = "MINUS",
-       [ FILTER_OP_RSHIFT ] = "RSHIFT",
-       [ FILTER_OP_LSHIFT ] = "LSHIFT",
+       [ FILTER_OP_BIT_RSHIFT ] = "BIT_RSHIFT",
+       [ FILTER_OP_BIT_LSHIFT ] = "BIT_LSHIFT",
        [ FILTER_OP_BIT_AND ] = "BIT_AND",
        [ FILTER_OP_BIT_OR ] = "BIT_OR",
        [ FILTER_OP_BIT_XOR ] = "BIT_XOR",
@@ -169,6 +169,8 @@ static const char *opnames[] = {
        [ FILTER_OP_LOAD_FIELD_STRING ] = "LOAD_FIELD_STRING",
        [ FILTER_OP_LOAD_FIELD_SEQUENCE ] = "LOAD_FIELD_SEQUENCE",
        [ FILTER_OP_LOAD_FIELD_DOUBLE ] = "LOAD_FIELD_DOUBLE",
+
+       [ FILTER_OP_UNARY_BIT_NOT ] = "UNARY_BIT_NOT",
 };
 
 const char *lttng_filter_print_op(enum filter_op op)
This page took 0.030152 seconds and 4 git commands to generate.