Fix: alignment problems on targets not supporting unaligned access.
[lttng-tools.git] / src / lib / lttng-ctl / filter / filter-visitor-generate-bytecode.c
index 39f74591f2a433e791a97f71145d0ce474a827ed..8c6dc96ff236520de23ea0efa7ee7b37f1c20784 100644 (file)
@@ -107,11 +107,14 @@ int32_t bytecode_reserve(struct lttng_filter_bytecode_alloc **fb, uint32_t align
                return -EINVAL;
 
        if (new_alloc_len > old_alloc_len) {
+               struct lttng_filter_bytecode_alloc *newptr;
+
                new_alloc_len =
                        max_t(uint32_t, 1U << get_count_order(new_alloc_len), old_alloc_len << 1);
-               *fb = realloc(*fb, new_alloc_len);
-               if (!*fb)
+               newptr = realloc(*fb, new_alloc_len);
+               if (!newptr)
                        return -ENOMEM;
+               *fb = newptr;
                /* We zero directly the memory from start of allocation. */
                memset(&((char *) *fb)[old_alloc_len], 0, new_alloc_len - old_alloc_len);
                (*fb)->alloc_len = new_alloc_len;
@@ -219,7 +222,7 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node)
                if (!insn)
                        return -ENOMEM;
                insn->op = FILTER_OP_LOAD_S64;
-               *(int64_t *) insn->data = node->u.load.u.num;
+               memcpy(insn->data, &node->u.load.u.num, sizeof(int64_t));
                ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
                free(insn);
                return ret;
@@ -234,12 +237,13 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node)
                if (!insn)
                        return -ENOMEM;
                insn->op = FILTER_OP_LOAD_DOUBLE;
-               *(double *) insn->data = node->u.load.u.flt;
+               memcpy(insn->data, &node->u.load.u.flt, sizeof(double));
                ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
                free(insn);
                return ret;
        }
-       case IR_DATA_FIELD_REF:
+       case IR_DATA_FIELD_REF: /* fall-through */
+       case IR_DATA_GET_CONTEXT_REF:
        {
                struct load_op *insn;
                uint32_t insn_len = sizeof(struct load_op)
@@ -251,7 +255,17 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node)
                insn = calloc(insn_len, 1);
                if (!insn)
                        return -ENOMEM;
-               insn->op = FILTER_OP_LOAD_FIELD_REF;
+               switch(node->data_type) {
+               case IR_DATA_FIELD_REF:
+                       insn->op = FILTER_OP_LOAD_FIELD_REF;
+                       break;
+               case IR_DATA_GET_CONTEXT_REF:
+                       insn->op = FILTER_OP_GET_CONTEXT_REF;
+                       break;
+               default:
+                       free(insn);
+                       return -EINVAL;
+               }
                ref_offset.offset = (uint16_t) -1U;
                memcpy(insn->data, &ref_offset, sizeof(ref_offset));
                /* reloc_offset points to struct load_op */
@@ -411,11 +425,13 @@ int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node)
        if (ret)
                return ret;
        /* Cast to s64 if float or field ref */
-       if (node->u.binary.left->data_type == IR_DATA_FIELD_REF
+       if ((node->u.binary.left->data_type == IR_DATA_FIELD_REF
+                               || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF)
                        || node->u.binary.left->data_type == IR_DATA_FLOAT) {
                struct cast_op cast_insn;
 
-               if (node->u.binary.left->data_type == IR_DATA_FIELD_REF) {
+               if (node->u.binary.left->data_type == IR_DATA_FIELD_REF
+                               || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF) {
                        cast_insn.op = FILTER_OP_CAST_TO_S64;
                } else {
                        cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64;
@@ -448,11 +464,13 @@ int visit_node_logical(struct filter_parser_ctx *ctx, struct ir_op *node)
        if (ret)
                return ret;
        /* Cast to s64 if float or field ref */
-       if (node->u.binary.right->data_type == IR_DATA_FIELD_REF
+       if ((node->u.binary.right->data_type == IR_DATA_FIELD_REF
+                               || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF)
                        || node->u.binary.right->data_type == IR_DATA_FLOAT) {
                struct cast_op cast_insn;
 
-               if (node->u.binary.right->data_type == IR_DATA_FIELD_REF) {
+               if (node->u.binary.right->data_type == IR_DATA_FIELD_REF
+                               || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF) {
                        cast_insn.op = FILTER_OP_CAST_TO_S64;
                } else {
                        cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64;
This page took 0.024954 seconds and 4 git commands to generate.