Fix: segmentation fault on filter interpretation in "switch" mode
[lttng-ust.git] / src / lib / lttng-ust / lttng-bytecode-interpreter.c
index cb128a692adda5de9901429964c2bdf96d535bc8..89ad1f92eb06d4ae1afc421beadb22d79827fc0d 100644 (file)
 #include <urcu/rculist.h>
 #include <lttng/ust-endian.h>
 #include <lttng/ust-events.h>
-#include "ust-events-internal.h"
+#include "lib/lttng-ust/events.h"
 
 #include "lttng-bytecode.h"
-#include "string-utils.h"
+#include "common/strutils.h"
 
 
 /*
@@ -153,6 +153,7 @@ int stack_strcmp(struct estack *stack, int top, const char *cmp_type __attribute
 int lttng_bytecode_interpret_error(
                struct lttng_ust_bytecode_runtime *bytecode_runtime __attribute__((unused)),
                const char *stack_data __attribute__((unused)),
+               struct lttng_ust_probe_ctx *probe_ctx __attribute__((unused)),
                void *ctx __attribute__((unused)))
 {
        return LTTNG_UST_BYTECODE_INTERPRETER_ERROR;
@@ -165,7 +166,7 @@ int lttng_bytecode_interpret_error(
  */
 
 #define START_OP                                                       \
-       start_pc = &bytecode->data[0];                                  \
+       start_pc = &bytecode->code[0];                                  \
        for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;    \
                        pc = next_pc) {                                 \
                dbg_printf("Executing op %s (%u)\n",                    \
@@ -215,6 +216,7 @@ LABEL_##name
                (reg_type == REG_U64 || reg_type == REG_S64)
 
 static int context_get_index(struct lttng_ust_ctx *ctx,
+               struct lttng_ust_probe_ctx *probe_ctx,
                struct load_ptr *ptr,
                uint32_t idx)
 {
@@ -230,7 +232,7 @@ static int context_get_index(struct lttng_ust_ctx *ctx,
 
        switch (field->type->type) {
        case lttng_ust_type_integer:
-               ctx_field->get_value(ctx_field->priv, &v);
+               ctx_field->get_value(ctx_field->priv, probe_ctx, &v);
                if (lttng_ust_get_type_integer(field->type)->signedness) {
                        ptr->object_type = OBJECT_TYPE_S64;
                        ptr->u.s64 = v.u.s64;
@@ -240,13 +242,14 @@ static int context_get_index(struct lttng_ust_ctx *ctx,
                        ptr->u.u64 = v.u.s64;   /* Cast. */
                        ptr->ptr = &ptr->u.u64;
                }
+               ptr->rev_bo = lttng_ust_get_type_integer(field->type)->reverse_byte_order;
                break;
        case lttng_ust_type_enum:
        {
                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->priv, &v);
+               ctx_field->get_value(ctx_field->priv, probe_ctx, &v);
                if (itype->signedness) {
                        ptr->object_type = OBJECT_TYPE_SIGNED_ENUM;
                        ptr->u.s64 = v.u.s64;
@@ -256,6 +259,7 @@ static int context_get_index(struct lttng_ust_ctx *ctx,
                        ptr->u.u64 = v.u.s64;   /* Cast. */
                        ptr->ptr = &ptr->u.u64;
                }
+               ptr->rev_bo = itype->reverse_byte_order;
                break;
        }
        case lttng_ust_type_array:
@@ -268,7 +272,7 @@ static int context_get_index(struct lttng_ust_ctx *ctx,
                        return -EINVAL;
                }
                ptr->object_type = OBJECT_TYPE_STRING;
-               ctx_field->get_value(ctx_field->priv, &v);
+               ctx_field->get_value(ctx_field->priv, probe_ctx, &v);
                ptr->ptr = v.u.str;
                break;
        case lttng_ust_type_sequence:
@@ -281,22 +285,23 @@ static int context_get_index(struct lttng_ust_ctx *ctx,
                        return -EINVAL;
                }
                ptr->object_type = OBJECT_TYPE_STRING;
-               ctx_field->get_value(ctx_field->priv, &v);
+               ctx_field->get_value(ctx_field->priv, probe_ctx, &v);
                ptr->ptr = v.u.str;
                break;
        case lttng_ust_type_string:
                ptr->object_type = OBJECT_TYPE_STRING;
-               ctx_field->get_value(ctx_field->priv, &v);
+               ctx_field->get_value(ctx_field->priv, probe_ctx, &v);
                ptr->ptr = v.u.str;
                break;
        case lttng_ust_type_float:
                ptr->object_type = OBJECT_TYPE_DOUBLE;
-               ctx_field->get_value(ctx_field->priv, &v);
+               ctx_field->get_value(ctx_field->priv, probe_ctx, &v);
                ptr->u.d = v.u.d;
                ptr->ptr = &ptr->u.d;
+               ptr->rev_bo = lttng_ust_get_type_float(field->type)->reverse_byte_order;
                break;
        case lttng_ust_type_dynamic:
-               ctx_field->get_value(ctx_field->priv, &v);
+               ctx_field->get_value(ctx_field->priv, probe_ctx, &v);
                switch (v.sel) {
                case LTTNG_UST_DYNAMIC_TYPE_NONE:
                        return -EINVAL;
@@ -307,6 +312,11 @@ static int context_get_index(struct lttng_ust_ctx *ctx,
                        ptr->object_type = OBJECT_TYPE_U64;
                        ptr->u.u64 = v.u.u64;
                        ptr->ptr = &ptr->u.u64;
+                       /*
+                        * struct lttng_ust_ctx_value does not currently
+                        * feature a byte order field.
+                        */
+                       ptr->rev_bo = false;
                        dbg_printf("context get index dynamic u64 %" PRIi64 "\n", ptr->u.u64);
                        break;
                case LTTNG_UST_DYNAMIC_TYPE_S8:
@@ -316,6 +326,11 @@ static int context_get_index(struct lttng_ust_ctx *ctx,
                        ptr->object_type = OBJECT_TYPE_S64;
                        ptr->u.s64 = v.u.s64;
                        ptr->ptr = &ptr->u.s64;
+                       /*
+                        * struct lttng_ust_ctx_value does not currently
+                        * feature a byte order field.
+                        */
+                       ptr->rev_bo = false;
                        dbg_printf("context get index dynamic s64 %" PRIi64 "\n", ptr->u.s64);
                        break;
                case LTTNG_UST_DYNAMIC_TYPE_FLOAT:
@@ -323,6 +338,11 @@ static int context_get_index(struct lttng_ust_ctx *ctx,
                        ptr->object_type = OBJECT_TYPE_DOUBLE;
                        ptr->u.d = v.u.d;
                        ptr->ptr = &ptr->u.d;
+                       /*
+                        * struct lttng_ust_ctx_value does not currently
+                        * feature a byte order field.
+                        */
+                       ptr->rev_bo = false;
                        dbg_printf("context get index dynamic double %g\n", ptr->u.d);
                        break;
                case LTTNG_UST_DYNAMIC_TYPE_STRING:
@@ -343,6 +363,7 @@ static int context_get_index(struct lttng_ust_ctx *ctx,
 }
 
 static int dynamic_get_index(struct lttng_ust_ctx *ctx,
+               struct lttng_ust_probe_ctx *probe_ctx,
                struct bytecode_runtime *runtime,
                uint64_t index, struct estack_entry *stack_top)
 {
@@ -403,6 +424,7 @@ static int dynamic_get_index(struct lttng_ust_ctx *ctx,
        case LOAD_ROOT_APP_CONTEXT:     /* Fall-through */
        {
                ret = context_get_index(ctx,
+                               probe_ctx,
                                &stack_top->u.ptr,
                                gid->ctx_index);
                if (ret) {
@@ -457,7 +479,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                dbg_printf("op load field s16\n");
                tmp = *(int16_t *) stack_top->u.ptr.ptr;
                if (stack_top->u.ptr.rev_bo)
-                       tmp = bswap_16(tmp);
+                       tmp = lttng_ust_bswap_16(tmp);
                stack_top->u.v = tmp;
                stack_top->type = REG_S64;
                break;
@@ -469,7 +491,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                dbg_printf("op load field s32\n");
                tmp = *(int32_t *) stack_top->u.ptr.ptr;
                if (stack_top->u.ptr.rev_bo)
-                       tmp = bswap_32(tmp);
+                       tmp = lttng_ust_bswap_32(tmp);
                stack_top->u.v = tmp;
                stack_top->type = REG_S64;
                break;
@@ -481,7 +503,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                dbg_printf("op load field s64\n");
                tmp = *(int64_t *) stack_top->u.ptr.ptr;
                if (stack_top->u.ptr.rev_bo)
-                       tmp = bswap_64(tmp);
+                       tmp = lttng_ust_bswap_64(tmp);
                stack_top->u.v = tmp;
                stack_top->type = REG_S64;
                break;
@@ -493,7 +515,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                dbg_printf("op load field signed enumeration\n");
                tmp = *(int64_t *) stack_top->u.ptr.ptr;
                if (stack_top->u.ptr.rev_bo)
-                       tmp = bswap_64(tmp);
+                       tmp = lttng_ust_bswap_64(tmp);
                stack_top->u.v = tmp;
                stack_top->type = REG_S64;
                break;
@@ -510,7 +532,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                dbg_printf("op load field u16\n");
                tmp = *(uint16_t *) stack_top->u.ptr.ptr;
                if (stack_top->u.ptr.rev_bo)
-                       tmp = bswap_16(tmp);
+                       tmp = lttng_ust_bswap_16(tmp);
                stack_top->u.v = tmp;
                stack_top->type = REG_U64;
                break;
@@ -522,7 +544,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                dbg_printf("op load field u32\n");
                tmp = *(uint32_t *) stack_top->u.ptr.ptr;
                if (stack_top->u.ptr.rev_bo)
-                       tmp = bswap_32(tmp);
+                       tmp = lttng_ust_bswap_32(tmp);
                stack_top->u.v = tmp;
                stack_top->type = REG_U64;
                break;
@@ -534,7 +556,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                dbg_printf("op load field u64\n");
                tmp = *(uint64_t *) stack_top->u.ptr.ptr;
                if (stack_top->u.ptr.rev_bo)
-                       tmp = bswap_64(tmp);
+                       tmp = lttng_ust_bswap_64(tmp);
                stack_top->u.v = tmp;
                stack_top->type = REG_U64;
                break;
@@ -546,7 +568,7 @@ static int dynamic_load_field(struct estack_entry *stack_top)
                dbg_printf("op load field unsigned enumeration\n");
                tmp = *(uint64_t *) stack_top->u.ptr.ptr;
                if (stack_top->u.ptr.rev_bo)
-                       tmp = bswap_64(tmp);
+                       tmp = lttng_ust_bswap_64(tmp);
                stack_top->u.v = tmp;
                stack_top->type = REG_U64;
                break;
@@ -711,6 +733,7 @@ again:
  */
 int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode,
                const char *interpreter_stack_data,
+               struct lttng_ust_probe_ctx *probe_ctx,
                void *caller_ctx)
 {
        struct bytecode_runtime *bytecode = caa_container_of(ust_bytecode, struct bytecode_runtime, p);
@@ -2138,7 +2161,7 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode,
                        dbg_printf("get context ref offset %u type dynamic\n",
                                ref->offset);
                        ctx_field = &ctx->fields[ref->offset];
-                       ctx_field->get_value(ctx_field->priv, &v);
+                       ctx_field->get_value(ctx_field->priv, probe_ctx, &v);
                        estack_push(stack, top, ax, bx, ax_t, bx_t);
                        switch (v.sel) {
                        case LTTNG_UST_DYNAMIC_TYPE_NONE:
@@ -2186,7 +2209,7 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode,
                        dbg_printf("get context ref offset %u type string\n",
                                ref->offset);
                        ctx_field = &ctx->fields[ref->offset];
-                       ctx_field->get_value(ctx_field->priv, &v);
+                       ctx_field->get_value(ctx_field->priv, probe_ctx, &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)) {
@@ -2213,7 +2236,7 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode,
                        dbg_printf("get context ref offset %u type s64\n",
                                ref->offset);
                        ctx_field = &ctx->fields[ref->offset];
-                       ctx_field->get_value(ctx_field->priv, &v);
+                       ctx_field->get_value(ctx_field->priv, probe_ctx, &v);
                        estack_push(stack, top, ax, bx, ax_t, bx_t);
                        estack_ax_v = v.u.s64;
                        estack_ax_t = REG_S64;
@@ -2232,7 +2255,7 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode,
                        dbg_printf("get context ref offset %u type double\n",
                                ref->offset);
                        ctx_field = &ctx->fields[ref->offset];
-                       ctx_field->get_value(ctx_field->priv, &v);
+                       ctx_field->get_value(ctx_field->priv, probe_ctx, &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;
@@ -2316,7 +2339,7 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode,
                        struct get_index_u16 *index = (struct get_index_u16 *) insn->data;
 
                        dbg_printf("op get index u16\n");
-                       ret = dynamic_get_index(ctx, bytecode, index->index, estack_ax(stack, top));
+                       ret = dynamic_get_index(ctx, probe_ctx, bytecode, index->index, estack_ax(stack, top));
                        if (ret)
                                goto end;
                        estack_ax_v = estack_ax(stack, top)->u.v;
@@ -2331,7 +2354,7 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode,
                        struct get_index_u64 *index = (struct get_index_u64 *) insn->data;
 
                        dbg_printf("op get index u64\n");
-                       ret = dynamic_get_index(ctx, bytecode, index->index, estack_ax(stack, top));
+                       ret = dynamic_get_index(ctx, probe_ctx, bytecode, index->index, estack_ax(stack, top));
                        if (ret)
                                goto end;
                        estack_ax_v = estack_ax(stack, top)->u.v;
@@ -2511,8 +2534,9 @@ end:
 /*
  * Return LTTNG_UST_EVENT_FILTER_ACCEPT or LTTNG_UST_EVENT_FILTER_REJECT.
  */
-int lttng_ust_interpret_event_filter(struct lttng_ust_event_common *event,
+int lttng_ust_interpret_event_filter(const struct lttng_ust_event_common *event,
                const char *interpreter_stack_data,
+               struct lttng_ust_probe_ctx *probe_ctx,
                void *event_filter_ctx __attribute__((unused)))
 {
        struct lttng_ust_bytecode_runtime *filter_bc_runtime;
@@ -2522,7 +2546,7 @@ int lttng_ust_interpret_event_filter(struct lttng_ust_event_common *event,
 
        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)) {
+                               interpreter_stack_data, probe_ctx, &bytecode_filter_ctx) == LTTNG_UST_BYTECODE_INTERPRETER_OK)) {
                        if (caa_unlikely(bytecode_filter_ctx.result == LTTNG_UST_BYTECODE_FILTER_ACCEPT)) {
                                filter_record = true;
                                break;
This page took 0.028225 seconds and 4 git commands to generate.