X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=src%2Flttng-filter-validator.c;h=3353be2b374cf7a4520df8c6cfe7e0310009c8b0;hb=7ab8c61663d23386a58fb2f36ab8e22d1c0b1efd;hp=9057ee8a8c19d887b874436c4bd5a5cf9ee8c568;hpb=4ac5fbb7966e7a6ee4a0cb68c49713bc8c05206c;p=lttng-modules.git diff --git a/src/lttng-filter-validator.c b/src/lttng-filter-validator.c index 9057ee8a..3353be2b 100644 --- a/src/lttng-filter-validator.c +++ b/src/lttng-filter-validator.c @@ -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,10 @@ 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_PTR: case REG_TYPE_UNKNOWN: break; default: @@ -1176,6 +1203,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 +1276,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 +1324,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 +1337,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 +1354,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 +1381,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 +1390,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 +1404,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 +1414,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 +1428,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 +1439,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 +1467,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 +1575,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 +1633,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 +1665,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: {