X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-filter-validator.c;h=92455c80a554766830dda045ccd5f73d76dc5b09;hb=93c591bb3a90753ce66197f2c1e41c8ef554506f;hp=6e52065c2d81b40dcc417cc754b9bdfa7e93f789;hpb=47e5f13e885764eecde371627001d26da2a2f41f;p=lttng-ust.git diff --git a/liblttng-ust/lttng-filter-validator.c b/liblttng-ust/lttng-filter-validator.c index 6e52065c..92455c80 100644 --- a/liblttng-ust/lttng-filter-validator.c +++ b/liblttng-ust/lttng-filter-validator.c @@ -296,6 +296,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)) { @@ -310,8 +311,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: { ERR("unsupported bytecode op %u\n", (unsigned int) *(filter_opcode_t *) pc); @@ -357,6 +356,8 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, 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: @@ -378,6 +379,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, case FILTER_OP_UNARY_PLUS_DOUBLE: case FILTER_OP_UNARY_MINUS_DOUBLE: case FILTER_OP_UNARY_NOT_DOUBLE: + case FILTER_OP_UNARY_BIT_NOT: { if (unlikely(pc + sizeof(struct unary_op) > start_pc + bytecode->len)) { @@ -577,6 +579,7 @@ int validate_instruction_context(struct bytecode_runtime *bytecode, } case FILTER_OP_RETURN: + case FILTER_OP_RETURN_S64: { goto end; } @@ -587,8 +590,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: { ERR("unsupported bytecode op %u\n", (unsigned int) opcode); @@ -758,6 +759,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) @@ -804,6 +815,32 @@ int validate_instruction_context(struct bytecode_runtime *bytecode, } break; } + case FILTER_OP_UNARY_BIT_NOT: + { + if (!vstack_ax(stack)) { + ERR("Empty stack\n"); + ret = -EINVAL; + goto end; + } + switch (vstack_ax(stack)->type) { + default: + ERR("unknown register type\n"); + ret = -EINVAL; + goto end; + + case REG_STRING: + case REG_STAR_GLOB_STRING: + case REG_DOUBLE: + ERR("Unary bitwise op can only be applied to numeric registers\n"); + ret = -EINVAL; + goto end; + case REG_S64: + break; + case REG_UNKNOWN: + break; + } + break; + } case FILTER_OP_UNARY_PLUS_S64: case FILTER_OP_UNARY_MINUS_S64: @@ -1220,6 +1257,27 @@ int exec_insn(struct bytecode_runtime *bytecode, ret = 0; goto end; } + case FILTER_OP_RETURN_S64: + { + if (!vstack_ax(stack)) { + ERR("Empty stack\n"); + ret = -EINVAL; + goto end; + } + switch (vstack_ax(stack)->type) { + case REG_S64: + break; + default: + case REG_UNKNOWN: + ERR("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: @@ -1227,8 +1285,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: { ERR("unsupported bytecode op %u\n", (unsigned int) *(filter_opcode_t *) pc); @@ -1274,6 +1330,8 @@ int exec_insn(struct bytecode_runtime *bytecode, 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: @@ -1383,6 +1441,31 @@ int exec_insn(struct bytecode_runtime *bytecode, break; } + case FILTER_OP_UNARY_BIT_NOT: + { + /* Pop 1, push 1 */ + if (!vstack_ax(stack)) { + ERR("Empty stack\n"); + ret = -EINVAL; + goto end; + } + switch (vstack_ax(stack)->type) { + case REG_UNKNOWN: + case REG_S64: + break; + case REG_DOUBLE: + default: + ERR("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; + } + case FILTER_OP_UNARY_NOT_DOUBLE: { /* Pop 1, push 1 */