-/*
+/* SPDX-License-Identifier: MIT
+ *
* lttng-filter-interpreter.c
*
* LTTng modules filter interpreter.
*
* Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
*/
-#include <linux/uaccess.h>
+#include <wrapper/uaccess.h>
#include <wrapper/frame.h>
#include <wrapper/types.h>
#include <linux/swab.h>
char c;
/* Handle invalid access as end of string. */
- if (unlikely(!access_ok(VERIFY_READ,
+ if (unlikely(!lttng_access_ok(VERIFY_READ,
reg->u.s.user_str + offset,
sizeof(c))))
return '\0';
ret = -EINVAL;
goto end;
}
- stack_top->u.s.seq_len = SIZE_MAX;
+ stack_top->u.s.seq_len = LTTNG_SIZE_MAX;
stack_top->u.s.literal_type =
ESTACK_STRING_LITERAL_TYPE_NONE;
break;
[ 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,
+
+ [ FILTER_OP_RETURN_S64 ] = &&LABEL_FILTER_OP_RETURN_S64,
};
#endif /* #ifndef INTERPRETER_USE_SWITCH */
goto end;
OP(FILTER_OP_RETURN):
+ OP(FILTER_OP_RETURN_S64):
/* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */
retval = !!estack_ax_v;
ret = 0;
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;
+
+ /* Catch undefined behavior. */
+ if (unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
+ ret = -EINVAL;
+ goto end;
+ }
+ res = ((uint64_t) estack_bx_v >> (uint32_t) 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;
+
+ /* Catch undefined behavior. */
+ if (unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
+ ret = -EINVAL;
+ goto end;
+ }
+ res = ((uint64_t) estack_bx_v << (uint32_t) 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;
- res = (estack_bx_v & estack_ax_v);
+ res = ((uint64_t) estack_bx_v & (uint64_t) estack_ax_v);
estack_pop(stack, top, ax, bx);
estack_ax_v = res;
next_pc += sizeof(struct binary_op);
{
int64_t res;
- res = (estack_bx_v | estack_ax_v);
+ res = ((uint64_t) estack_bx_v | (uint64_t) estack_ax_v);
estack_pop(stack, top, ax, bx);
estack_ax_v = res;
next_pc += sizeof(struct binary_op);
{
int64_t res;
- res = (estack_bx_v ^ estack_ax_v);
+ res = ((uint64_t) estack_bx_v ^ (uint64_t) estack_ax_v);
estack_pop(stack, top, ax, bx);
estack_ax_v = res;
next_pc += sizeof(struct binary_op);
goto end;
+ OP(FILTER_OP_UNARY_BIT_NOT):
+ {
+ estack_ax_v = ~(uint64_t) estack_ax_v;
+ next_pc += sizeof(struct unary_op);
+ PO;
+ }
+
OP(FILTER_OP_UNARY_PLUS_S64):
{
next_pc += sizeof(struct unary_op);
ret = -EINVAL;
goto end;
}
- estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
+ estack_ax(stack, top)->u.s.seq_len = LTTNG_SIZE_MAX;
estack_ax(stack, top)->u.s.literal_type =
ESTACK_STRING_LITERAL_TYPE_NONE;
next_pc += sizeof(struct load_op);