Fix: add missing semicolons after MSG, DBG, ERR print macros
[lttng-tools.git] / src / lib / lttng-ctl / filter / filter-visitor-generate-bytecode.c
index 71da21c8a5108a8f0114aa9389c16d92bc54240a..e28abd57271ecec91936d19e2918c8c1b1aa986c 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include "align.h"
+#include <common/align.h>
+#include <common/compat/string.h>
+
 #include "filter-bytecode.h"
 #include "filter-ir.h"
 #include "filter-ast.h"
 
+#include <common/macros.h>
+
 #ifndef max_t
 #define max_t(type, a, b)      ((type) ((a) > (b) ? (a) : (b)))
 #endif
 
-//#define INIT_ALLOC_SIZE              PAGE_SIZE
 #define INIT_ALLOC_SIZE                4
 
 static
 int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx,
                struct ir_op *node);
 
-static inline int fls(unsigned int x)
-{
-       int r = 32;
-
-       if (!x)
-               return 0;
-       if (!(x & 0xFFFF0000U)) {
-               x <<= 16;
-               r -= 16;
-       }
-       if (!(x & 0xFF000000U)) {
-               x <<= 8;
-               r -= 8;
-       }
-       if (!(x & 0xF0000000U)) {
-               x <<= 4;
-               r -= 4;
-       }
-       if (!(x & 0xC0000000U)) {
-               x <<= 2;
-               r -= 2;
-       }
-       if (!(x & 0x80000000U)) {
-               x <<= 1;
-               r -= 1;
-       }
-       return r;
-}
-
 static inline int get_count_order(unsigned int count)
 {
        int order;
 
-       order = fls(count) - 1;
+       order = lttng_fls(count) - 1;
        if (count & (count - 1))
                order++;
        return order;
@@ -80,11 +54,14 @@ static inline int get_count_order(unsigned int count)
 static
 int bytecode_init(struct lttng_filter_bytecode_alloc **fb)
 {
-       *fb = calloc(sizeof(struct lttng_filter_bytecode_alloc) + INIT_ALLOC_SIZE, 1);
+       uint32_t alloc_len;
+
+       alloc_len = sizeof(struct lttng_filter_bytecode_alloc) + INIT_ALLOC_SIZE;
+       *fb = calloc(alloc_len, 1);
        if (!*fb) {
                return -ENOMEM;
        } else {
-               (*fb)->alloc_len = INIT_ALLOC_SIZE;
+               (*fb)->alloc_len = alloc_len;
                return 0;
        }
 }
@@ -94,20 +71,25 @@ int32_t bytecode_reserve(struct lttng_filter_bytecode_alloc **fb, uint32_t align
 {
        int32_t ret;
        uint32_t padding = offset_align((*fb)->b.len, align);
+       uint32_t new_len = (*fb)->b.len + padding + len;
+       uint32_t new_alloc_len = sizeof(struct lttng_filter_bytecode_alloc) + new_len;
+       uint32_t old_alloc_len = (*fb)->alloc_len;
 
-       if ((*fb)->b.len + padding + len > (*fb)->alloc_len) {
-               uint32_t new_len =
-                       max_t(uint32_t, 1U << get_count_order((*fb)->b.len + padding + len),
-                               (*fb)->alloc_len << 1);
-               uint32_t old_len = (*fb)->alloc_len;
+       if (new_len > LTTNG_FILTER_MAX_LEN)
+               return -EINVAL;
 
-               if (new_len > 0xFFFF)
-                       return -EINVAL;
-               *fb = realloc(*fb, sizeof(struct lttng_filter_bytecode_alloc) + new_len);
-               if (!*fb)
+       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);
+               newptr = realloc(*fb, new_alloc_len);
+               if (!newptr)
                        return -ENOMEM;
-               memset(&(*fb)->b.data[old_len], 0, new_len - old_len);
-               (*fb)->alloc_len = new_len;
+               *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;
        }
        (*fb)->b.len += padding;
        ret = (*fb)->b.len;
@@ -212,7 +194,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;
@@ -227,27 +209,44 @@ 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)
                        + sizeof(struct field_ref);
                struct field_ref ref_offset;
+               uint32_t reloc_offset_u32;
                uint16_t reloc_offset;
 
                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 */
-               reloc_offset = bytecode_get_len(&ctx->bytecode->b);
+               reloc_offset_u32 = bytecode_get_len(&ctx->bytecode->b);
+               if (reloc_offset_u32 > LTTNG_FILTER_MAX_LEN - 1) {
+                       free(insn);
+                       return -EINVAL;
+               }
+               reloc_offset = (uint16_t) reloc_offset_u32;
                ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
                if (ret) {
                        free(insn);
@@ -398,11 +397,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;
@@ -435,11 +436,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;
@@ -486,16 +489,25 @@ int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx,
        }
 }
 
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
 void filter_bytecode_free(struct filter_parser_ctx *ctx)
 {
-       free(ctx->bytecode);
-       ctx->bytecode = NULL;
-       free(ctx->bytecode_reloc);
-       ctx->bytecode_reloc = NULL;
+       if (!ctx) {
+               return;
+       }
+
+       if (ctx->bytecode) {
+               free(ctx->bytecode);
+               ctx->bytecode = NULL;
+       }
+
+       if (ctx->bytecode_reloc) {
+               free(ctx->bytecode_reloc);
+               ctx->bytecode_reloc = NULL;
+       }
 }
 
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
 int filter_visitor_bytecode_generate(struct filter_parser_ctx *ctx)
 {
        int ret;
This page took 0.025898 seconds and 4 git commands to generate.