X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=liblttng-ust%2Flttng-bytecode-interpreter.c;h=46351a25f3ed4e23cd68a6edc7deafa7327794cc;hb=ddabe860f4cf41a4206a8157d83e6b9354f85cb5;hp=9d7258f7dd81530c9e892912ac017a602e1625b1;hpb=04aa13f8c2944839f6514e3841b93057b443a783;p=lttng-ust.git diff --git a/liblttng-ust/lttng-bytecode-interpreter.c b/liblttng-ust/lttng-bytecode-interpreter.c index 9d7258f7..46351a25 100644 --- a/liblttng-ust/lttng-bytecode-interpreter.c +++ b/liblttng-ust/lttng-bytecode-interpreter.c @@ -1,37 +1,19 @@ /* - * lttng-bytecode-interpreter.c - * - * LTTng UST bytecode interpreter. + * SPDX-License-Identifier: MIT * * Copyright (C) 2010-2016 Mathieu Desnoyers * - * 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. + * LTTng UST bytecode interpreter. */ #define _LGPL_SOURCE #include #include -#include -#include +#include #include #include +#include "ust-events-internal.h" #include "lttng-bytecode.h" #include "string-utils.h" @@ -172,6 +154,13 @@ uint64_t lttng_bytecode_filter_interpret_false(void *filter_data, return LTTNG_INTERPRETER_DISCARD; } +uint64_t lttng_bytecode_capture_interpret_false(void *capture_data, + const char *capture_stack_data, + struct lttng_interpreter_output *output) +{ + return LTTNG_INTERPRETER_DISCARD; +} + #ifdef INTERPRETER_USE_SWITCH /* @@ -183,7 +172,7 @@ uint64_t lttng_bytecode_filter_interpret_false(void *filter_data, for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \ pc = next_pc) { \ dbg_printf("Executing op %s (%u)\n", \ - print_op((unsigned int) *(bytecode_opcode_t *) pc), \ + lttng_bytecode_print_op((unsigned int) *(bytecode_opcode_t *) pc), \ (unsigned int) *(bytecode_opcode_t *) pc); \ switch (*(bytecode_opcode_t *) pc) { @@ -234,7 +223,7 @@ static int context_get_index(struct lttng_ctx *ctx, { struct lttng_ctx_field *ctx_field; - struct lttng_event_field *field; + struct lttng_ust_event_field *field; struct lttng_ctx_value v; ctx_field = &ctx->fields[idx]; @@ -255,41 +244,23 @@ static int context_get_index(struct lttng_ctx *ctx, ptr->ptr = &ptr->u.u64; } break; - case atype_enum: /* Fall-through */ case atype_enum_nestable: { const struct lttng_integer_type *itype; - if (field->type.atype == atype_enum) { - itype = &field->type.u.legacy.basic.enumeration.container_type; - } else { - itype = &field->type.u.enum_nestable.container_type->u.integer; - } + itype = &field->type.u.enum_nestable.container_type->u.integer; ctx_field->get_value(ctx_field, &v); if (itype->signedness) { - ptr->object_type = OBJECT_TYPE_S64; + ptr->object_type = OBJECT_TYPE_SIGNED_ENUM; ptr->u.s64 = v.u.s64; ptr->ptr = &ptr->u.s64; } else { - ptr->object_type = OBJECT_TYPE_U64; + ptr->object_type = OBJECT_TYPE_UNSIGNED_ENUM; ptr->u.u64 = v.u.s64; /* Cast. */ ptr->ptr = &ptr->u.u64; } break; } - case atype_array: - if (field->type.u.legacy.array.elem_type.atype != atype_integer) { - ERR("Array nesting only supports integer types."); - return -EINVAL; - } - if (field->type.u.legacy.array.elem_type.u.basic.integer.encoding == lttng_encode_none) { - ERR("Only string arrays are supported for contexts."); - return -EINVAL; - } - ptr->object_type = OBJECT_TYPE_STRING; - ctx_field->get_value(ctx_field, &v); - ptr->ptr = v.u.str; - break; case atype_array_nestable: if (field->type.u.array_nestable.elem_type->atype != atype_integer) { ERR("Array nesting only supports integer types."); @@ -303,19 +274,6 @@ static int context_get_index(struct lttng_ctx *ctx, ctx_field->get_value(ctx_field, &v); ptr->ptr = v.u.str; break; - case atype_sequence: - if (field->type.u.legacy.sequence.elem_type.atype != atype_integer) { - ERR("Sequence nesting only supports integer types."); - return -EINVAL; - } - if (field->type.u.legacy.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) { - ERR("Only string sequences are supported for contexts."); - return -EINVAL; - } - ptr->object_type = OBJECT_TYPE_STRING; - ctx_field->get_value(ctx_field, &v); - ptr->ptr = v.u.str; - break; case atype_sequence_nestable: if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) { ERR("Sequence nesting only supports integer types."); @@ -345,12 +303,25 @@ static int context_get_index(struct lttng_ctx *ctx, switch (v.sel) { case LTTNG_UST_DYNAMIC_TYPE_NONE: return -EINVAL; + case LTTNG_UST_DYNAMIC_TYPE_U8: + case LTTNG_UST_DYNAMIC_TYPE_U16: + case LTTNG_UST_DYNAMIC_TYPE_U32: + case LTTNG_UST_DYNAMIC_TYPE_U64: + ptr->object_type = OBJECT_TYPE_U64; + ptr->u.u64 = v.u.u64; + ptr->ptr = &ptr->u.u64; + dbg_printf("context get index dynamic u64 %" PRIi64 "\n", ptr->u.u64); + break; + case LTTNG_UST_DYNAMIC_TYPE_S8: + case LTTNG_UST_DYNAMIC_TYPE_S16: + case LTTNG_UST_DYNAMIC_TYPE_S32: case LTTNG_UST_DYNAMIC_TYPE_S64: ptr->object_type = OBJECT_TYPE_S64; ptr->u.s64 = v.u.s64; ptr->ptr = &ptr->u.s64; dbg_printf("context get index dynamic s64 %" PRIi64 "\n", ptr->u.s64); break; + case LTTNG_UST_DYNAMIC_TYPE_FLOAT: case LTTNG_UST_DYNAMIC_TYPE_DOUBLE: ptr->object_type = OBJECT_TYPE_DOUBLE; ptr->u.d = v.u.d; @@ -367,9 +338,6 @@ static int context_get_index(struct lttng_ctx *ctx, return -EINVAL; } break; - case atype_struct: - ERR("Structure type cannot be loaded."); - return -EINVAL; default: ERR("Unknown type: %d", (int) field->type.atype); return -EINVAL; @@ -399,8 +367,7 @@ static int dynamic_get_index(struct lttng_ctx *ctx, stack_top->u.ptr.ptr = ptr; stack_top->u.ptr.object_type = gid->elem.type; stack_top->u.ptr.rev_bo = gid->elem.rev_bo; - assert(stack_top->u.ptr.field->type.atype == atype_array || - stack_top->u.ptr.field->type.atype == atype_array_nestable); + assert(stack_top->u.ptr.field->type.atype == atype_array_nestable); stack_top->u.ptr.field = NULL; break; } @@ -419,8 +386,7 @@ static int dynamic_get_index(struct lttng_ctx *ctx, stack_top->u.ptr.ptr = ptr; stack_top->u.ptr.object_type = gid->elem.type; stack_top->u.ptr.rev_bo = gid->elem.rev_bo; - assert(stack_top->u.ptr.field->type.atype == atype_sequence || - stack_top->u.ptr.field->type.atype == atype_sequence_nestable); + assert(stack_top->u.ptr.field->type.atype == atype_sequence_nestable); stack_top->u.ptr.field = NULL; break; } @@ -523,6 +489,18 @@ static int dynamic_load_field(struct estack_entry *stack_top) stack_top->type = REG_S64; break; } + case OBJECT_TYPE_SIGNED_ENUM: + { + int64_t tmp; + + 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); + stack_top->u.v = tmp; + stack_top->type = REG_S64; + break; + } case OBJECT_TYPE_U8: dbg_printf("op load field u8\n"); stack_top->u.v = *(uint8_t *) stack_top->u.ptr.ptr; @@ -564,6 +542,18 @@ static int dynamic_load_field(struct estack_entry *stack_top) stack_top->type = REG_U64; break; } + case OBJECT_TYPE_UNSIGNED_ENUM: + { + uint64_t tmp; + + 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); + stack_top->u.v = tmp; + stack_top->type = REG_U64; + break; + } case OBJECT_TYPE_DOUBLE: memcpy(&stack_top->u.d, stack_top->u.ptr.ptr, @@ -683,6 +673,20 @@ again: output->u.sequence.nr_elem = ax->u.ptr.field->type.u.array_nestable.length; output->u.sequence.nested_type = ax->u.ptr.field->type.u.array_nestable.elem_type; break; + case OBJECT_TYPE_SIGNED_ENUM: + ret = dynamic_load_field(ax); + if (ret) + return ret; + output->type = LTTNG_INTERPRETER_TYPE_SIGNED_ENUM; + output->u.s = ax->u.v; + break; + case OBJECT_TYPE_UNSIGNED_ENUM: + ret = dynamic_load_field(ax); + if (ret) + return ret; + output->type = LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM; + output->u.u = ax->u.v; + break; case OBJECT_TYPE_STRUCT: case OBJECT_TYPE_VARIANT: default: @@ -700,9 +704,12 @@ again: } /* - * Return 0 (discard), or raise the 0x1 flag (log event). - * Currently, other flags are kept for future extensions and have no - * effect. + * 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. */ static uint64_t bytecode_interpret(void *interpreter_data, @@ -710,7 +717,7 @@ uint64_t bytecode_interpret(void *interpreter_data, struct lttng_interpreter_output *output) { struct bytecode_runtime *bytecode = interpreter_data; - struct lttng_ctx *ctx = rcu_dereference(*bytecode->p.pctx); + struct lttng_ctx *ctx = lttng_ust_rcu_dereference(*bytecode->p.priv->pctx); void *pc, *next_pc, *start_pc; int ret = -EINVAL; uint64_t retval = 0; @@ -2493,6 +2500,14 @@ uint64_t lttng_bytecode_filter_interpret(void *filter_data, return bytecode_interpret(filter_data, filter_stack_data, NULL); } +uint64_t lttng_bytecode_capture_interpret(void *capture_data, + const char *capture_stack_data, + struct lttng_interpreter_output *output) +{ + return bytecode_interpret(capture_data, capture_stack_data, + (struct lttng_interpreter_output *) output); +} + #undef START_OP #undef OP #undef PO