#include <stdint.h>
#include <lttng/urcu/pointer.h>
+#include <urcu/rculist.h>
#include <lttng/ust-endian.h>
#include <lttng/ust-events.h>
#include "ust-events-internal.h"
}
static
-int stack_star_glob_match(struct estack *stack, int top, const char *cmp_type)
+int stack_star_glob_match(struct estack *stack, int top,
+ const char *cmp_type __attribute__((unused)))
{
const char *pattern;
const char *candidate;
}
static
-int stack_strcmp(struct estack *stack, int top, const char *cmp_type)
+int stack_strcmp(struct estack *stack, int top, const char *cmp_type __attribute__((unused)))
{
const char *p = estack_bx(stack, top)->u.s.str, *q = estack_ax(stack, top)->u.s.str;
int ret;
return diff;
}
-int lttng_bytecode_interpret_error(struct lttng_ust_bytecode_runtime *bytecode_runtime,
- const char *stack_data,
- void *ctx)
+int lttng_bytecode_interpret_error(
+ struct lttng_ust_bytecode_runtime *bytecode_runtime __attribute__((unused)),
+ const char *stack_data __attribute__((unused)),
+ void *ctx __attribute__((unused)))
{
return LTTNG_UST_BYTECODE_INTERPRETER_ERROR;
}
uint32_t idx)
{
- struct lttng_ust_ctx_field *ctx_field;
- struct lttng_ust_event_field *field;
+ const struct lttng_ust_ctx_field *ctx_field;
+ const struct lttng_ust_event_field *field;
struct lttng_ust_ctx_value v;
- ctx_field = ctx->fields[idx];
+ ctx_field = &ctx->fields[idx];
field = ctx_field->event_field;
ptr->type = LOAD_OBJECT;
ptr->field = field;
switch (field->type->type) {
case lttng_ust_type_integer:
- ctx_field->get_value(ctx_field, &v);
+ ctx_field->get_value(ctx_field->priv, &v);
if (lttng_ust_get_type_integer(field->type)->signedness) {
ptr->object_type = OBJECT_TYPE_S64;
ptr->u.s64 = v.u.s64;
const struct lttng_ust_type_integer *itype;
itype = lttng_ust_get_type_integer(lttng_ust_get_type_enum(field->type)->container_type);
- ctx_field->get_value(ctx_field, &v);
+ ctx_field->get_value(ctx_field->priv, &v);
if (itype->signedness) {
ptr->object_type = OBJECT_TYPE_SIGNED_ENUM;
ptr->u.s64 = v.u.s64;
return -EINVAL;
}
ptr->object_type = OBJECT_TYPE_STRING;
- ctx_field->get_value(ctx_field, &v);
+ ctx_field->get_value(ctx_field->priv, &v);
ptr->ptr = v.u.str;
break;
case lttng_ust_type_sequence:
return -EINVAL;
}
ptr->object_type = OBJECT_TYPE_STRING;
- ctx_field->get_value(ctx_field, &v);
+ ctx_field->get_value(ctx_field->priv, &v);
ptr->ptr = v.u.str;
break;
case lttng_ust_type_string:
ptr->object_type = OBJECT_TYPE_STRING;
- ctx_field->get_value(ctx_field, &v);
+ ctx_field->get_value(ctx_field->priv, &v);
ptr->ptr = v.u.str;
break;
case lttng_ust_type_float:
ptr->object_type = OBJECT_TYPE_DOUBLE;
- ctx_field->get_value(ctx_field, &v);
+ ctx_field->get_value(ctx_field->priv, &v);
ptr->u.d = v.u.d;
ptr->ptr = &ptr->u.d;
break;
case lttng_ust_type_dynamic:
- ctx_field->get_value(ctx_field, &v);
+ ctx_field->get_value(ctx_field->priv, &v);
switch (v.sel) {
case LTTNG_UST_DYNAMIC_TYPE_NONE:
return -EINVAL;
}
/*
- * For `output` equal to NULL:
- * Return 0 (discard), or raise the 0x1 flag (log event).
- * Currently, other flags are kept for future extensions and have no
- * effect.
- * For `output` not equal to NULL:
- * Return 0 on success, negative error value on error.
+ * Return LTTNG_UST_BYTECODE_INTERPRETER_OK on success.
+ * Return LTTNG_UST_BYTECODE_INTERPRETER_ERROR on error.
+ *
+ * For FILTER bytecode: expect a struct lttng_ust_bytecode_filter_ctx *
+ * as @ctx argument.
+ * For CAPTURE bytecode: expect a struct lttng_interpreter_output *
+ * as @ctx argument.
*/
int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode,
const char *interpreter_stack_data,
void *caller_ctx)
{
struct bytecode_runtime *bytecode = caa_container_of(ust_bytecode, struct bytecode_runtime, p);
- struct lttng_ust_ctx *ctx = lttng_ust_rcu_dereference(*ust_bytecode->priv->pctx);
+ struct lttng_ust_ctx *ctx = lttng_ust_rcu_dereference(*ust_bytecode->pctx);
void *pc, *next_pc, *start_pc;
int ret = -EINVAL, retval = 0;
struct estack _stack;
case REG_DOUBLE:
case REG_STRING:
case REG_PTR:
- if (ust_bytecode->priv->type != LTTNG_UST_BYTECODE_TYPE_CAPTURE) {
+ if (ust_bytecode->type != LTTNG_UST_BYTECODE_TYPE_CAPTURE) {
ret = -EINVAL;
goto end;
}
JUMP_TO(BYTECODE_OP_CAST_DOUBLE_TO_S64);
case REG_U64:
estack_ax_t = REG_S64;
- next_pc += sizeof(struct cast_op);
+ next_pc += sizeof(struct cast_op); /* Fall-through */
case REG_STRING: /* Fall-through */
case REG_STAR_GLOB_STRING:
ret = -EINVAL;
{
struct load_op *insn = (struct load_op *) pc;
struct field_ref *ref = (struct field_ref *) insn->data;
- struct lttng_ust_ctx_field *ctx_field;
+ const struct lttng_ust_ctx_field *ctx_field;
struct lttng_ust_ctx_value v;
dbg_printf("get context ref offset %u type dynamic\n",
ref->offset);
- ctx_field = ctx->fields[ref->offset];
- ctx_field->get_value(ctx_field, &v);
+ ctx_field = &ctx->fields[ref->offset];
+ ctx_field->get_value(ctx_field->priv, &v);
estack_push(stack, top, ax, bx, ax_t, bx_t);
switch (v.sel) {
case LTTNG_UST_DYNAMIC_TYPE_NONE:
{
struct load_op *insn = (struct load_op *) pc;
struct field_ref *ref = (struct field_ref *) insn->data;
- struct lttng_ust_ctx_field *ctx_field;
+ const struct lttng_ust_ctx_field *ctx_field;
struct lttng_ust_ctx_value v;
dbg_printf("get context ref offset %u type string\n",
ref->offset);
- ctx_field = ctx->fields[ref->offset];
- ctx_field->get_value(ctx_field, &v);
+ ctx_field = &ctx->fields[ref->offset];
+ ctx_field->get_value(ctx_field->priv, &v);
estack_push(stack, top, ax, bx, ax_t, bx_t);
estack_ax(stack, top)->u.s.str = v.u.str;
if (unlikely(!estack_ax(stack, top)->u.s.str)) {
{
struct load_op *insn = (struct load_op *) pc;
struct field_ref *ref = (struct field_ref *) insn->data;
- struct lttng_ust_ctx_field *ctx_field;
+ const struct lttng_ust_ctx_field *ctx_field;
struct lttng_ust_ctx_value v;
dbg_printf("get context ref offset %u type s64\n",
ref->offset);
- ctx_field = ctx->fields[ref->offset];
- ctx_field->get_value(ctx_field, &v);
+ ctx_field = &ctx->fields[ref->offset];
+ ctx_field->get_value(ctx_field->priv, &v);
estack_push(stack, top, ax, bx, ax_t, bx_t);
estack_ax_v = v.u.s64;
estack_ax_t = REG_S64;
{
struct load_op *insn = (struct load_op *) pc;
struct field_ref *ref = (struct field_ref *) insn->data;
- struct lttng_ust_ctx_field *ctx_field;
+ const struct lttng_ust_ctx_field *ctx_field;
struct lttng_ust_ctx_value v;
dbg_printf("get context ref offset %u type double\n",
ref->offset);
- ctx_field = ctx->fields[ref->offset];
- ctx_field->get_value(ctx_field, &v);
+ ctx_field = &ctx->fields[ref->offset];
+ ctx_field->get_value(ctx_field->priv, &v);
estack_push(stack, top, ax, bx, ax_t, bx_t);
memcpy(&estack_ax(stack, top)->u.d, &v.u.d, sizeof(struct literal_double));
estack_ax_t = REG_DOUBLE;
return LTTNG_UST_BYTECODE_INTERPRETER_ERROR;
/* Prepare output. */
- switch (ust_bytecode->priv->type) {
+ switch (ust_bytecode->type) {
case LTTNG_UST_BYTECODE_TYPE_FILTER:
{
struct lttng_ust_bytecode_filter_ctx *filter_ctx =
return LTTNG_UST_BYTECODE_INTERPRETER_OK;
}
+/*
+ * Return LTTNG_UST_EVENT_FILTER_ACCEPT or LTTNG_UST_EVENT_FILTER_REJECT.
+ */
+int lttng_ust_interpret_event_filter(struct lttng_ust_event_common *event,
+ const char *interpreter_stack_data,
+ void *event_filter_ctx __attribute__((unused)))
+{
+ struct lttng_ust_bytecode_runtime *filter_bc_runtime;
+ struct cds_list_head *filter_bytecode_runtime_head = &event->priv->filter_bytecode_runtime_head;
+ struct lttng_ust_bytecode_filter_ctx bytecode_filter_ctx;
+ bool filter_record = false;
+
+ cds_list_for_each_entry_rcu(filter_bc_runtime, filter_bytecode_runtime_head, node) {
+ if (caa_likely(filter_bc_runtime->interpreter_func(filter_bc_runtime,
+ interpreter_stack_data, &bytecode_filter_ctx) == LTTNG_UST_BYTECODE_INTERPRETER_OK)) {
+ if (caa_unlikely(bytecode_filter_ctx.result == LTTNG_UST_BYTECODE_FILTER_ACCEPT)) {
+ filter_record = true;
+ break;
+ }
+ }
+ }
+ if (filter_record)
+ return LTTNG_UST_EVENT_FILTER_ACCEPT;
+ else
+ return LTTNG_UST_EVENT_FILTER_REJECT;
+}
+
#undef START_OP
#undef OP
#undef PO