projects
/
lttng-ust.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Version 2.8.0-rc1
[lttng-ust.git]
/
liblttng-ust
/
lttng-filter-validator.c
diff --git
a/liblttng-ust/lttng-filter-validator.c
b/liblttng-ust/lttng-filter-validator.c
index 6cdfd8c164764e075bab11a5cb8234c51765890f..dc50774de5b6deb6c20efdcd9c7f3cc905b3bb07 100644
(file)
--- a/
liblttng-ust/lttng-filter-validator.c
+++ b/
liblttng-ust/lttng-filter-validator.c
@@
-74,7
+74,9
@@
int merge_points_compare(const struct vstack *stacka,
len = stacka->top + 1;
assert(len >= 0);
for (i = 0; i < len; i++) {
len = stacka->top + 1;
assert(len >= 0);
for (i = 0; i < len; i++) {
- if (stacka->e[i].type != stackb->e[i].type)
+ if (stacka->e[i].type != REG_UNKNOWN
+ && stackb->e[i].type != REG_UNKNOWN
+ && stacka->e[i].type != stackb->e[i].type)
return 1;
}
return 0;
return 1;
}
return 0;
@@
-118,22
+120,28
@@
int merge_point_add_check(struct cds_lfht *ht, unsigned long target_pc,
/*
* Binary comparators use top of stack and top of stack -1.
/*
* Binary comparators use top of stack and top of stack -1.
+ * Return 0 if typing is known to match, 1 if typing is dynamic
+ * (unknown), negative error value on error.
*/
static
int bin_op_compare_check(struct vstack *stack, const char *str)
{
if (unlikely(!vstack_ax(stack) || !vstack_bx(stack)))
*/
static
int bin_op_compare_check(struct vstack *stack, const char *str)
{
if (unlikely(!vstack_ax(stack) || !vstack_bx(stack)))
- goto error_
unknown
;
+ goto error_
empty
;
switch (vstack_ax(stack)->type) {
default:
switch (vstack_ax(stack)->type) {
default:
- goto error_
unknown
;
+ goto error_
type
;
+ case REG_UNKNOWN:
+ goto unknown;
case REG_STRING:
switch (vstack_bx(stack)->type) {
default:
case REG_STRING:
switch (vstack_bx(stack)->type) {
default:
- goto error_
unknown
;
+ goto error_
type
;
+ case REG_UNKNOWN:
+ goto unknown;
case REG_STRING:
break;
case REG_S64:
case REG_STRING:
break;
case REG_S64:
@@
-145,11
+153,12
@@
int bin_op_compare_check(struct vstack *stack, const char *str)
case REG_DOUBLE:
switch (vstack_bx(stack)->type) {
default:
case REG_DOUBLE:
switch (vstack_bx(stack)->type) {
default:
- goto error_
unknown
;
+ goto error_
type
;
+ case REG_UNKNOWN:
+ goto unknown;
case REG_STRING:
goto error_mismatch;
case REG_STRING:
goto error_mismatch;
-
case REG_S64:
case REG_DOUBLE:
break;
case REG_S64:
case REG_DOUBLE:
break;
@@
-158,12
+167,20
@@
int bin_op_compare_check(struct vstack *stack, const char *str)
}
return 0;
}
return 0;
-
error_
unknown:
- return
-EINVAL
;
+unknown:
+ return
1
;
error_mismatch:
ERR("type mismatch for '%s' binary operator\n", str);
return -EINVAL;
error_mismatch:
ERR("type mismatch for '%s' binary operator\n", str);
return -EINVAL;
+
+error_empty:
+ ERR("empty stack for '%s' binary operator\n", str);
+ return -EINVAL;
+
+error_type:
+ ERR("unknown type for '%s' binary operator\n", str);
+ return -EINVAL;
}
/*
}
/*
@@
-295,11
+312,6
@@
int bytecode_validate_overflow(struct bytecode_runtime *bytecode,
}
/* get context ref */
case FILTER_OP_GET_CONTEXT_REF:
}
/* get context ref */
case FILTER_OP_GET_CONTEXT_REF:
- {
- ERR("Unknown field ref type\n");
- ret = -EINVAL;
- break;
- }
case FILTER_OP_LOAD_FIELD_REF_STRING:
case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
case FILTER_OP_LOAD_FIELD_REF_S64:
case FILTER_OP_LOAD_FIELD_REF_STRING:
case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
case FILTER_OP_LOAD_FIELD_REF_S64:
@@
-391,7
+403,7
@@
unsigned long delete_all_nodes(struct cds_lfht *ht)
/*
* Return value:
/*
* Return value:
- * 0: success
+ *
>=
0: success
* <0: error
*/
static
* <0: error
*/
static
@@
-438,42
+450,42
@@
int validate_instruction_context(struct bytecode_runtime *bytecode,
case FILTER_OP_EQ:
{
ret = bin_op_compare_check(stack, "==");
case FILTER_OP_EQ:
{
ret = bin_op_compare_check(stack, "==");
- if (ret)
+ if (ret
< 0
)
goto end;
break;
}
case FILTER_OP_NE:
{
ret = bin_op_compare_check(stack, "!=");
goto end;
break;
}
case FILTER_OP_NE:
{
ret = bin_op_compare_check(stack, "!=");
- if (ret)
+ if (ret
< 0
)
goto end;
break;
}
case FILTER_OP_GT:
{
ret = bin_op_compare_check(stack, ">");
goto end;
break;
}
case FILTER_OP_GT:
{
ret = bin_op_compare_check(stack, ">");
- if (ret)
+ if (ret
< 0
)
goto end;
break;
}
case FILTER_OP_LT:
{
ret = bin_op_compare_check(stack, "<");
goto end;
break;
}
case FILTER_OP_LT:
{
ret = bin_op_compare_check(stack, "<");
- if (ret)
+ if (ret
< 0
)
goto end;
break;
}
case FILTER_OP_GE:
{
ret = bin_op_compare_check(stack, ">=");
goto end;
break;
}
case FILTER_OP_GE:
{
ret = bin_op_compare_check(stack, ">=");
- if (ret)
+ if (ret
< 0
)
goto end;
break;
}
case FILTER_OP_LE:
{
ret = bin_op_compare_check(stack, "<=");
goto end;
break;
}
case FILTER_OP_LE:
{
ret = bin_op_compare_check(stack, "<=");
- if (ret)
+ if (ret
< 0
)
goto end;
break;
}
goto end;
break;
}
@@
-604,6
+616,8
@@
int validate_instruction_context(struct bytecode_runtime *bytecode,
break;
case REG_DOUBLE:
break;
break;
case REG_DOUBLE:
break;
+ case REG_UNKNOWN:
+ break;
}
break;
}
}
break;
}
@@
-653,8
+667,9
@@
int validate_instruction_context(struct bytecode_runtime *bytecode,
ret = -EINVAL;
goto end;
}
ret = -EINVAL;
goto end;
}
- if (vstack_ax(stack)->type != REG_S64) {
- ERR("Logical comparator expects S64 register\n");
+ if (vstack_ax(stack)->type != REG_S64
+ && vstack_ax(stack)->type != REG_UNKNOWN) {
+ ERR("Logical comparator expects S64 or dynamic register\n");
ret = -EINVAL;
goto end;
}
ret = -EINVAL;
goto end;
}
@@
-745,6
+760,8
@@
int validate_instruction_context(struct bytecode_runtime *bytecode,
break;
case REG_DOUBLE:
break;
break;
case REG_DOUBLE:
break;
+ case REG_UNKNOWN:
+ break;
}
if (insn->op == FILTER_OP_CAST_DOUBLE_TO_S64) {
if (vstack_ax(stack)->type != REG_DOUBLE) {
}
if (insn->op == FILTER_OP_CAST_DOUBLE_TO_S64) {
if (vstack_ax(stack)->type != REG_DOUBLE) {
@@
-763,9
+780,12
@@
int validate_instruction_context(struct bytecode_runtime *bytecode,
/* get context ref */
case FILTER_OP_GET_CONTEXT_REF:
{
/* get context ref */
case FILTER_OP_GET_CONTEXT_REF:
{
- ERR("Unknown get context ref type\n");
- ret = -EINVAL;
- goto end;
+ struct load_op *insn = (struct load_op *) pc;
+ struct field_ref *ref = (struct field_ref *) insn->data;
+
+ dbg_printf("Validate get context ref offset %u type dynamic\n",
+ ref->offset);
+ break;
}
case FILTER_OP_GET_CONTEXT_REF_STRING:
{
}
case FILTER_OP_GET_CONTEXT_REF_STRING:
{
@@
-821,7
+841,7
@@
int validate_instruction_all_contexts(struct bytecode_runtime *bytecode,
/* Validate the context resulting from the previous instruction */
ret = validate_instruction_context(bytecode, stack, start_pc, pc);
/* Validate the context resulting from the previous instruction */
ret = validate_instruction_context(bytecode, stack, start_pc, pc);
- if (ret)
+ if (ret
< 0
)
return ret;
/* Validate merge points */
return ret;
/* Validate merge points */
@@
-959,10
+979,23
@@
int exec_insn(struct bytecode_runtime *bytecode,
/* unary */
case FILTER_OP_UNARY_PLUS:
case FILTER_OP_UNARY_MINUS:
/* unary */
case FILTER_OP_UNARY_PLUS:
case FILTER_OP_UNARY_MINUS:
- case FILTER_OP_UNARY_NOT:
+ {
+ /* Pop 1, push 1 */
+ if (!vstack_ax(stack)) {
+ ERR("Empty stack\n");
+ ret = -EINVAL;
+ goto end;
+ }
+ vstack_ax(stack)->type = REG_UNKNOWN;
+ next_pc += sizeof(struct unary_op);
+ break;
+ }
+
case FILTER_OP_UNARY_PLUS_S64:
case FILTER_OP_UNARY_MINUS_S64:
case FILTER_OP_UNARY_PLUS_S64:
case FILTER_OP_UNARY_MINUS_S64:
+ case FILTER_OP_UNARY_NOT:
case FILTER_OP_UNARY_NOT_S64:
case FILTER_OP_UNARY_NOT_S64:
+ case FILTER_OP_UNARY_NOT_DOUBLE:
{
/* Pop 1, push 1 */
if (!vstack_ax(stack)) {
{
/* Pop 1, push 1 */
if (!vstack_ax(stack)) {
@@
-977,7
+1010,6
@@
int exec_insn(struct bytecode_runtime *bytecode,
case FILTER_OP_UNARY_PLUS_DOUBLE:
case FILTER_OP_UNARY_MINUS_DOUBLE:
case FILTER_OP_UNARY_PLUS_DOUBLE:
case FILTER_OP_UNARY_MINUS_DOUBLE:
- case FILTER_OP_UNARY_NOT_DOUBLE:
{
/* Pop 1, push 1 */
if (!vstack_ax(stack)) {
{
/* Pop 1, push 1 */
if (!vstack_ax(stack)) {
@@
-1024,9
+1056,13
@@
int exec_insn(struct bytecode_runtime *bytecode,
/* get context ref */
case FILTER_OP_GET_CONTEXT_REF:
{
/* get context ref */
case FILTER_OP_GET_CONTEXT_REF:
{
- ERR("Unknown get context ref type\n");
- ret = -EINVAL;
- goto end;
+ if (vstack_push(stack)) {
+ ret = -EINVAL;
+ goto end;
+ }
+ vstack_ax(stack)->type = REG_UNKNOWN;
+ next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
+ break;
}
case FILTER_OP_LOAD_FIELD_REF_STRING:
case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
}
case FILTER_OP_LOAD_FIELD_REF_STRING:
case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
@@
-1171,7
+1207,7
@@
int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode)
/*
* For each instruction, validate the current context
* (traversal of entire execution flow), and validate
/*
* For each instruction, validate the current context
* (traversal of entire execution flow), and validate
- * all
merge points targeting this instruction.
+ * all merge points targeting this instruction.
*/
ret = validate_instruction_all_contexts(bytecode, merge_points,
&stack, start_pc, pc);
*/
ret = validate_instruction_all_contexts(bytecode, merge_points,
&stack, start_pc, pc);
This page took
0.028463 seconds
and
4
git commands to generate.