*/
#define _LGPL_SOURCE
-#include <urcu-bp.h>
+#include <stddef.h>
+#include <stdint.h>
#include <time.h>
-#include "lttng-filter.h"
+#include <urcu-bp.h>
#include <urcu/rculfhash.h>
+
+#include "lttng-filter.h"
#include "lttng-hash-helper.h"
#include "string-utils.h"
+#include "ust-events-internal.h"
/*
* Number of merge points for hash table size. Hash table initialized to
}
break;
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
goto error_mismatch;
}
break;
case REG_STAR_GLOB_STRING:
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
goto error_mismatch;
}
break;
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
switch (vstack_bx(stack)->type) {
default:
case REG_STAR_GLOB_STRING:
goto error_mismatch;
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
break;
}
case REG_UNKNOWN:
goto unknown;
case REG_S64:
+ case REG_U64:
switch (vstack_bx(stack)->type) {
default:
goto error_type;
case REG_UNKNOWN:
goto unknown;
case REG_S64:
+ case REG_U64:
break;
}
break;
}
case FILTER_OP_RETURN:
+ case FILTER_OP_RETURN_S64:
{
if (unlikely(pc + sizeof(struct return_op)
> start_pc + bytecode->len)) {
if (unlikely(pc + sizeof(struct load_op) + sizeof(struct get_symbol)
> start_pc + bytecode->len)) {
ret = -ERANGE;
+ break;
}
ret = validate_get_symbol(bytecode, sym);
break;
}
case FILTER_OP_RETURN:
+ case FILTER_OP_RETURN_S64:
{
goto end;
}
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:
+ ERR("Unexpected register type for s64 comparator\n");
+ ret = -EINVAL;
+ goto end;
+ }
+ switch (vstack_bx(stack)->type) {
+ case REG_S64:
+ case REG_U64:
+ break;
+ default:
ERR("Unexpected register type for s64 comparator\n");
ret = -EINVAL;
goto end;
ret = -EINVAL;
goto end;
}
- if (vstack_ax(stack)->type != REG_S64 && vstack_bx(stack)->type != REG_DOUBLE) {
+ switch (vstack_ax(stack)->type) {
+ case REG_S64:
+ case REG_U64:
+ break;
+ default:
+ ERR("Double-S64 operator has unexpected register types\n");
+ ret = -EINVAL;
+ goto end;
+ }
+ switch (vstack_bx(stack)->type) {
+ case REG_DOUBLE:
+ break;
+ default:
ERR("Double-S64 operator has unexpected register types\n");
ret = -EINVAL;
goto end;
ret = -EINVAL;
goto end;
}
- if (vstack_ax(stack)->type != REG_DOUBLE && vstack_bx(stack)->type != REG_S64) {
+ switch (vstack_ax(stack)->type) {
+ case REG_DOUBLE:
+ break;
+ default:
+ ERR("S64-Double operator has unexpected register types\n");
+ ret = -EINVAL;
+ goto end;
+ }
+ switch (vstack_bx(stack)->type) {
+ case REG_S64:
+ case REG_U64:
+ break;
+ default:
ERR("S64-Double operator has unexpected register types\n");
ret = -EINVAL;
goto end;
goto end;
case REG_S64:
break;
+ case REG_U64:
+ break;
case REG_DOUBLE:
break;
case REG_UNKNOWN:
goto end;
case REG_S64:
break;
+ case REG_U64:
+ break;
case REG_UNKNOWN:
break;
}
ret = -EINVAL;
goto end;
}
- if (vstack_ax(stack)->type != REG_S64) {
+ if (vstack_ax(stack)->type != REG_S64 &&
+ vstack_ax(stack)->type != REG_U64) {
ERR("Invalid register type\n");
ret = -EINVAL;
goto end;
goto end;
}
if (vstack_ax(stack)->type != REG_S64
+ && vstack_ax(stack)->type != REG_U64
&& vstack_ax(stack)->type != REG_UNKNOWN) {
- ERR("Logical comparator expects S64 or dynamic register\n");
+ ERR("Logical comparator expects S64, U64 or dynamic register\n");
ret = -EINVAL;
goto end;
}
goto end;
case REG_S64:
break;
+ case REG_U64:
+ break;
case REG_DOUBLE:
break;
case REG_UNKNOWN:
}
switch (vstack_ax(stack)->type) {
case REG_S64:
+ case REG_U64:
case REG_UNKNOWN:
break;
default:
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:
+ case REG_U64:
+ 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:
case FILTER_OP_LT_S64_DOUBLE:
case FILTER_OP_GE_S64_DOUBLE:
case FILTER_OP_LE_S64_DOUBLE:
+ {
+ /* Pop 2, push 1 */
+ if (vstack_pop(stack)) {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (!vstack_ax(stack)) {
+ ERR("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_UNKNOWN:
+ break;
+ 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 binary_op);
+ break;
+ }
+
case FILTER_OP_BIT_RSHIFT:
case FILTER_OP_BIT_LSHIFT:
case FILTER_OP_BIT_AND:
}
switch (vstack_ax(stack)->type) {
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
case REG_STRING:
case REG_STAR_GLOB_STRING:
goto end;
}
- vstack_ax(stack)->type = REG_S64;
+ vstack_ax(stack)->type = REG_U64;
next_pc += sizeof(struct binary_op);
break;
}
case REG_UNKNOWN:
case REG_DOUBLE:
case REG_S64:
+ case REG_U64:
break;
default:
ERR("Unexpected register type %d for operation\n",
}
switch (vstack_ax(stack)->type) {
case REG_S64:
+ case REG_U64:
break;
default:
ERR("Unexpected register type %d for operation\n",
goto end;
}
- vstack_ax(stack)->type = REG_S64;
next_pc += sizeof(struct unary_op);
break;
}
case REG_UNKNOWN:
case REG_DOUBLE:
case REG_S64:
+ case REG_U64:
break;
default:
ERR("Unexpected register type %d for operation\n",
goto end;
}
- vstack_ax(stack)->type = REG_S64;
next_pc += sizeof(struct unary_op);
break;
}
switch (vstack_ax(stack)->type) {
case REG_UNKNOWN:
case REG_S64:
+ case REG_U64:
break;
case REG_DOUBLE:
default:
goto end;
}
- vstack_ax(stack)->type = REG_S64;
+ vstack_ax(stack)->type = REG_U64;
next_pc += sizeof(struct unary_op);
break;
}
/* 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:
ERR("Incorrect register type %d for operation\n",
}
switch (vstack_ax(stack)->type) {
case REG_S64:
+ case REG_U64:
case REG_DOUBLE:
case REG_UNKNOWN:
break;
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)) {
+ ERR("Empty stack\n");
+ ret = -EINVAL;
+ goto end;
+ }
+ if (vstack_ax(stack)->type != REG_PTR) {
+ ERR("Expecting pointer on top of stack\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:
ret = -EINVAL;
goto end;
}
- vstack_ax(stack)->type = REG_S64;
+ vstack_ax(stack)->type = REG_U64;
next_pc += sizeof(struct load_op);
break;
}