X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=src%2Flttng-filter-validator.c;h=3353be2b374cf7a4520df8c6cfe7e0310009c8b0;hb=7ab8c61663d23386a58fb2f36ab8e22d1c0b1efd;hp=f117eadf25a30977358ce1eb181ee195dd9ba222;hpb=5a15f70c5211ff4a398171a6971586e2948eb419;p=lttng-modules.git diff --git a/src/lttng-filter-validator.c b/src/lttng-filter-validator.c index f117eadf..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; @@ -215,13 +220,13 @@ int bin_op_bitwise_check(struct vstack *stack, filter_opcode_t opcode, case REG_DOUBLE: goto error_type; case REG_TYPE_UNKNOWN: - case REG_STRING: - case REG_STAR_GLOB_STRING: case REG_S64: + case REG_U64: goto unknown; } break; case REG_S64: + case REG_U64: switch (vstack_bx(stack)->type) { default: case REG_DOUBLE: @@ -229,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; @@ -709,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; @@ -767,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; } @@ -792,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; } @@ -808,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; @@ -827,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; @@ -1156,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: @@ -1178,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: @@ -1250,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: @@ -1268,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: @@ -1280,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; } @@ -1297,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: @@ -1323,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", @@ -1331,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; } @@ -1346,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: @@ -1355,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; } @@ -1370,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: @@ -1380,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; } @@ -1408,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", @@ -1515,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; @@ -1572,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: @@ -1588,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: {