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,
FILTER_OP_LOAD_FIELD_SEQUENCE = 96,
FILTER_OP_LOAD_FIELD_DOUBLE = 97,
+ FILTER_OP_UNARY_BIT_NOT = 98,
+
NR_FILTER_OPS,
};
[ 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,
[ 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 */
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;
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;
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);
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;
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:
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:
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:
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:
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)) {
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:
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)
}
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:
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:
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:
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:
[ 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",
[ 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)