bytecode: propagate `rev_bo` of element
[deliverable/lttng-ust.git] / liblttng-ust / lttng-filter-specialize.c
index 0a19896b43038fa11dc4120e1f469998bc40b3a0..947fde29288c222b6f6f384d208907c1c4a8daa4 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "lttng-filter.h"
 #include <lttng/align.h>
+#include "ust-events-internal.h"
 
 static int lttng_fls(int val)
 {
@@ -156,24 +157,24 @@ static int specialize_load_field(struct vstack_entry *stack_top,
                break;
        case OBJECT_TYPE_U8:
                dbg_printf("op load field u8\n");
-               stack_top->type = REG_S64;
+               stack_top->type = REG_U64;
                insn->op = FILTER_OP_LOAD_FIELD_U8;
                break;
        case OBJECT_TYPE_U16:
                dbg_printf("op load field u16\n");
-               stack_top->type = REG_S64;
+               stack_top->type = REG_U64;
                if (!stack_top->load.rev_bo)
                        insn->op = FILTER_OP_LOAD_FIELD_U16;
                break;
        case OBJECT_TYPE_U32:
                dbg_printf("op load field u32\n");
-               stack_top->type = REG_S64;
+               stack_top->type = REG_U64;
                if (!stack_top->load.rev_bo)
                        insn->op = FILTER_OP_LOAD_FIELD_U32;
                break;
        case OBJECT_TYPE_U64:
                dbg_printf("op load field u64\n");
-               stack_top->type = REG_S64;
+               stack_top->type = REG_U64;
                if (!stack_top->load.rev_bo)
                        insn->op = FILTER_OP_LOAD_FIELD_U64;
                break;
@@ -395,9 +396,7 @@ static int specialize_load_object(const struct lttng_event_field *field,
                struct vstack_load *load, bool is_context)
 {
        load->type = LOAD_OBJECT;
-       /*
-        * LTTng-UST layout all integer fields as s64 on the stack for the filter.
-        */
+
        switch (field->type.atype) {
        case atype_integer:
                if (field->type.u.integer.signedness)
@@ -532,6 +531,8 @@ static int specialize_context_lookup(struct lttng_ctx *ctx,
        memset(&gid, 0, sizeof(gid));
        gid.ctx_index = idx;
        gid.elem.type = load->object_type;
+       gid.elem.rev_bo = load->rev_bo;
+       gid.field = field;
        data_offset = bytecode_push_data(runtime, &gid,
                __alignof__(gid), sizeof(gid));
        if (data_offset < 0) {
@@ -585,6 +586,8 @@ static int specialize_app_context_lookup(struct lttng_ctx **pctx,
        memset(&gid, 0, sizeof(gid));
        gid.ctx_index = idx;
        gid.elem.type = load->object_type;
+       gid.elem.rev_bo = load->rev_bo;
+       gid.field = field;
        data_offset = bytecode_push_data(runtime, &gid,
                __alignof__(gid), sizeof(gid));
        if (data_offset < 0) {
@@ -598,14 +601,13 @@ end:
        return ret;
 }
 
-static int specialize_event_payload_lookup(struct lttng_event *event,
+static int specialize_payload_lookup(const struct lttng_event_desc *event_desc,
                struct bytecode_runtime *runtime,
                struct load_op *insn,
                struct vstack_load *load)
 {
        const char *name;
        uint16_t offset;
-       const struct lttng_event_desc *desc = event->desc;
        unsigned int i, nr_fields;
        bool found = false;
        uint32_t field_offset = 0;
@@ -614,11 +616,11 @@ static int specialize_event_payload_lookup(struct lttng_event *event,
        struct filter_get_index_data gid;
        ssize_t data_offset;
 
-       nr_fields = desc->nr_fields;
+       nr_fields = event_desc->nr_fields;
        offset = ((struct get_symbol *) insn->data)->offset;
        name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
        for (i = 0; i < nr_fields; i++) {
-               field = &desc->fields[i];
+               field = &event_desc->fields[i];
                if (field->u.ext.nofilter) {
                        continue;
                }
@@ -665,6 +667,8 @@ static int specialize_event_payload_lookup(struct lttng_event *event,
        memset(&gid, 0, sizeof(gid));
        gid.offset = field_offset;
        gid.elem.type = load->object_type;
+       gid.elem.rev_bo = load->rev_bo;
+       gid.field = field;
        data_offset = bytecode_push_data(runtime, &gid,
                __alignof__(gid), sizeof(gid));
        if (data_offset < 0) {
@@ -677,7 +681,7 @@ end:
        return ret;
 }
 
-int lttng_filter_specialize_bytecode(struct lttng_event *event,
+int lttng_filter_specialize_bytecode(const struct lttng_event_desc *event_desc,
                struct bytecode_runtime *bytecode)
 {
        void *pc, *next_pc, *start_pc;
@@ -700,13 +704,15 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                        goto end;
 
                case FILTER_OP_RETURN:
-                       if (vstack_ax(stack)->type == REG_S64)
+                       if (vstack_ax(stack)->type == REG_S64 ||
+                                       vstack_ax(stack)->type == REG_U64)
                                *(filter_opcode_t *) pc = FILTER_OP_RETURN_S64;
                        ret = 0;
                        goto end;
 
                case FILTER_OP_RETURN_S64:
-                       if (vstack_ax(stack)->type != REG_S64) {
+                       if (vstack_ax(stack)->type != REG_S64 &&
+                                       vstack_ax(stack)->type != REG_U64) {
                                ERR("Unexpected register type\n");
                                ret = -EINVAL;
                                goto end;
@@ -749,9 +755,11 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                insn->op = FILTER_OP_EQ_STAR_GLOB_STRING;
                                break;
                        case REG_S64:
+                       case REG_U64:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_EQ_S64;
                                else
                                        insn->op = FILTER_OP_EQ_DOUBLE_S64;
@@ -759,7 +767,8 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                        case REG_DOUBLE:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_EQ_S64_DOUBLE;
                                else
                                        insn->op = FILTER_OP_EQ_DOUBLE;
@@ -801,9 +810,11 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                insn->op = FILTER_OP_NE_STAR_GLOB_STRING;
                                break;
                        case REG_S64:
+                       case REG_U64:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_NE_S64;
                                else
                                        insn->op = FILTER_OP_NE_DOUBLE_S64;
@@ -811,7 +822,8 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                        case REG_DOUBLE:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_NE_S64_DOUBLE;
                                else
                                        insn->op = FILTER_OP_NE_DOUBLE;
@@ -849,9 +861,11 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                insn->op = FILTER_OP_GT_STRING;
                                break;
                        case REG_S64:
+                       case REG_U64:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_GT_S64;
                                else
                                        insn->op = FILTER_OP_GT_DOUBLE_S64;
@@ -859,7 +873,8 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                        case REG_DOUBLE:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_GT_S64_DOUBLE;
                                else
                                        insn->op = FILTER_OP_GT_DOUBLE;
@@ -897,9 +912,11 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                insn->op = FILTER_OP_LT_STRING;
                                break;
                        case REG_S64:
+                       case REG_U64:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_LT_S64;
                                else
                                        insn->op = FILTER_OP_LT_DOUBLE_S64;
@@ -907,7 +924,8 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                        case REG_DOUBLE:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_LT_S64_DOUBLE;
                                else
                                        insn->op = FILTER_OP_LT_DOUBLE;
@@ -945,9 +963,11 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                insn->op = FILTER_OP_GE_STRING;
                                break;
                        case REG_S64:
+                       case REG_U64:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_GE_S64;
                                else
                                        insn->op = FILTER_OP_GE_DOUBLE_S64;
@@ -955,7 +975,8 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                        case REG_DOUBLE:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_GE_S64_DOUBLE;
                                else
                                        insn->op = FILTER_OP_GE_DOUBLE;
@@ -968,7 +989,7 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                ret = -EINVAL;
                                goto end;
                        }
-                       vstack_ax(stack)->type = REG_S64;
+                       vstack_ax(stack)->type = REG_U64;
                        next_pc += sizeof(struct binary_op);
                        break;
                }
@@ -992,9 +1013,11 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                insn->op = FILTER_OP_LE_STRING;
                                break;
                        case REG_S64:
+                       case REG_U64:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_LE_S64;
                                else
                                        insn->op = FILTER_OP_LE_DOUBLE_S64;
@@ -1002,7 +1025,8 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                        case REG_DOUBLE:
                                if (vstack_bx(stack)->type == REG_UNKNOWN)
                                        break;
-                               if (vstack_bx(stack)->type == REG_S64)
+                               if (vstack_bx(stack)->type == REG_S64 ||
+                                               vstack_bx(stack)->type == REG_U64)
                                        insn->op = FILTER_OP_LE_S64_DOUBLE;
                                else
                                        insn->op = FILTER_OP_LE_DOUBLE;
@@ -1047,6 +1071,17 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                case FILTER_OP_LT_S64_DOUBLE:
                case FILTER_OP_GE_S64_DOUBLE:
                case FILTER_OP_LE_S64_DOUBLE:
+               {
+                       /* Pop 2, push 1 */
+                       if (vstack_pop(stack)) {
+                               ret = -EINVAL;
+                               goto end;
+                       }
+                       vstack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       break;
+               }
+
                case FILTER_OP_BIT_RSHIFT:
                case FILTER_OP_BIT_LSHIFT:
                case FILTER_OP_BIT_AND:
@@ -1075,6 +1110,7 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                goto end;
 
                        case REG_S64:
+                       case REG_U64:
                                insn->op = FILTER_OP_UNARY_PLUS_S64;
                                break;
                        case REG_DOUBLE:
@@ -1099,6 +1135,7 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                goto end;
 
                        case REG_S64:
+                       case REG_U64:
                                insn->op = FILTER_OP_UNARY_MINUS_S64;
                                break;
                        case REG_DOUBLE:
@@ -1123,6 +1160,7 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                goto end;
 
                        case REG_S64:
+                       case REG_U64:
                                insn->op = FILTER_OP_UNARY_NOT_S64;
                                break;
                        case REG_DOUBLE:
@@ -1296,6 +1334,7 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                insn->op = FILTER_OP_CAST_DOUBLE_TO_S64;
                                break;
                        case REG_UNKNOWN:
+                       case REG_U64:
                                break;
                        }
                        /* Pop 1, push 1 */
@@ -1371,13 +1410,20 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                case FILTER_OP_LOAD_FIELD_S16:
                case FILTER_OP_LOAD_FIELD_S32:
                case FILTER_OP_LOAD_FIELD_S64:
+               {
+                       /* Pop 1, push 1 */
+                       vstack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct load_op);
+                       break;
+               }
+
                case FILTER_OP_LOAD_FIELD_U8:
                case FILTER_OP_LOAD_FIELD_U16:
                case FILTER_OP_LOAD_FIELD_U32:
                case FILTER_OP_LOAD_FIELD_U64:
                {
                        /* Pop 1, push 1 */
-                       vstack_ax(stack)->type = REG_S64;
+                       vstack_ax(stack)->type = REG_U64;
                        next_pc += sizeof(struct load_op);
                        break;
                }
@@ -1427,7 +1473,7 @@ int lttng_filter_specialize_bytecode(struct lttng_event *event,
                                break;
                        case LOAD_ROOT_PAYLOAD:
                                /* Lookup event payload field. */
-                               ret = specialize_event_payload_lookup(event,
+                               ret = specialize_payload_lookup(event_desc,
                                        bytecode, insn,
                                        &vstack_ax(stack)->load);
                                if (ret)
This page took 0.029686 seconds and 5 git commands to generate.