From 6afbab01c56b1a634c7071e1e885759ac4fd0b7f Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 6 Apr 2020 16:43:09 -0400 Subject: [PATCH] common: add more bytecode helpers MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The common/bytecode/bytecode.c file already contains some helper functions that are used build bytecode. A following patch will require helpers for a few more operations. This patch factors them out of the filter-visitor-generate-bytecode.c file. No functional changes intended. Change-Id: I013e0dad3e0264d062e3e8733c05f7fbb4bda70c Signed-off-by: Simon Marchi Signed-off-by: Jérémie Galarneau Depends-on: lttng-ust: I5a800fc92e588c2a6a0e26282b0ad5f31c044479 --- src/common/bytecode/bytecode.c | 149 ++++++++++++++++++ src/common/bytecode/bytecode.h | 13 ++ .../filter/filter-visitor-generate-bytecode.c | 95 ++--------- 3 files changed, 175 insertions(+), 82 deletions(-) diff --git a/src/common/bytecode/bytecode.c b/src/common/bytecode/bytecode.c index 4f8c325b5..fb8985a00 100644 --- a/src/common/bytecode/bytecode.c +++ b/src/common/bytecode/bytecode.c @@ -100,6 +100,155 @@ int bytecode_push_logical(struct lttng_bytecode_alloc **fb, return 0; } +LTTNG_HIDDEN +int bytecode_push_get_payload_root(struct lttng_bytecode_alloc **bytecode) +{ + int ret; + struct load_op *insn; + const uint32_t insn_len = sizeof(struct load_op); + + insn = calloc(insn_len, 1); + if (!insn) { + ret = -ENOMEM; + goto end; + } + + insn->op = BYTECODE_OP_GET_PAYLOAD_ROOT; + ret = bytecode_push(bytecode, insn, 1, insn_len); + free(insn); +end: + return ret; +} + +LTTNG_HIDDEN +int bytecode_push_get_context_root(struct lttng_bytecode_alloc **bytecode) +{ + int ret; + struct load_op *insn; + const uint32_t insn_len = sizeof(struct load_op); + + insn = calloc(insn_len, 1); + if (!insn) { + ret = -ENOMEM; + goto end; + } + + insn->op = BYTECODE_OP_GET_CONTEXT_ROOT; + ret = bytecode_push(bytecode, insn, 1, insn_len); + free(insn); +end: + return ret; +} + +LTTNG_HIDDEN +int bytecode_push_get_app_context_root(struct lttng_bytecode_alloc **bytecode) +{ + int ret; + struct load_op *insn; + const uint32_t insn_len = sizeof(struct load_op); + + insn = calloc(insn_len, 1); + if (!insn) { + ret = -ENOMEM; + goto end; + } + + insn->op = BYTECODE_OP_GET_APP_CONTEXT_ROOT; + ret = bytecode_push(bytecode, insn, 1, insn_len); + free(insn); +end: + return ret; +} + +LTTNG_HIDDEN +int bytecode_push_get_index_u64(struct lttng_bytecode_alloc **bytecode, + uint64_t index) +{ + int ret; + struct load_op *insn; + struct get_index_u64 index_op_data; + const uint32_t insn_len = + sizeof(struct load_op) + sizeof(struct get_index_u64); + + insn = calloc(insn_len, 1); + if (!insn) { + ret = -ENOMEM; + goto end; + } + + insn->op = BYTECODE_OP_GET_INDEX_U64; + index_op_data.index = index; + memcpy(insn->data, &index_op_data, sizeof(index)); + ret = bytecode_push(bytecode, insn, 1, insn_len); + + free(insn); +end: + return ret; +} + +LTTNG_HIDDEN +int bytecode_push_get_symbol(struct lttng_bytecode_alloc **bytecode, + struct lttng_bytecode_alloc **bytecode_reloc, + const char *symbol) +{ + int ret; + struct load_op *insn; + struct get_symbol symbol_offset; + uint32_t reloc_offset_u32; + uint16_t reloc_offset; + uint32_t bytecode_reloc_offset_u32; + const uint32_t insn_len = + sizeof(struct load_op) + sizeof(struct get_symbol); + + insn = calloc(insn_len, 1); + if (!insn) { + ret = -ENOMEM; + goto end; + } + + insn->op = BYTECODE_OP_GET_SYMBOL; + + /* + * Get offset in the reloc portion at which the symbol name + * will end up at (GET_SYMBOL's operand points there). + */ + bytecode_reloc_offset_u32 = bytecode_get_len(&(*bytecode_reloc)->b) + + sizeof(reloc_offset); + symbol_offset.offset = (uint16_t) bytecode_reloc_offset_u32; + memcpy(insn->data, &symbol_offset, sizeof(symbol_offset)); + + /* + * Get offset in the bytecode where the opcode will end up at, + * the reloc offset points to it. + */ + reloc_offset_u32 = bytecode_get_len(&(*bytecode)->b); + if (reloc_offset_u32 > LTTNG_FILTER_MAX_LEN - 1) { + ret = -EINVAL; + goto end; + } + reloc_offset = (uint16_t) reloc_offset_u32; + + /* Append op in bytecode. */ + ret = bytecode_push(bytecode, insn, 1, insn_len); + if (ret) { + goto end; + } + + /* Append reloc offset. */ + ret = bytecode_push(bytecode_reloc, &reloc_offset, + 1, sizeof(reloc_offset)); + if (ret) { + goto end; + } + + /* Append symbol name. */ + ret = bytecode_push(bytecode_reloc, symbol, 1, strlen(symbol) + 1); + +end: + free(insn); + return ret; +} + /* * Allocate an lttng_bytecode object and copy the given original bytecode. * diff --git a/src/common/bytecode/bytecode.h b/src/common/bytecode/bytecode.h index 151ca8a0f..498f7f000 100644 --- a/src/common/bytecode/bytecode.h +++ b/src/common/bytecode/bytecode.h @@ -245,6 +245,19 @@ LTTNG_HIDDEN int bytecode_push_logical(struct lttng_bytecode_alloc **fb, LTTNG_HIDDEN struct lttng_bytecode *lttng_bytecode_copy( const struct lttng_bytecode *orig_f); +LTTNG_HIDDEN int bytecode_push_get_payload_root( + struct lttng_bytecode_alloc **bytecode); +LTTNG_HIDDEN int bytecode_push_get_context_root( + struct lttng_bytecode_alloc **bytecode); +LTTNG_HIDDEN int bytecode_push_get_app_context_root( + struct lttng_bytecode_alloc **bytecode); +LTTNG_HIDDEN int bytecode_push_get_index_u64( + struct lttng_bytecode_alloc **bytecode, uint64_t index); +LTTNG_HIDDEN int bytecode_push_get_symbol( + struct lttng_bytecode_alloc **bytecode, + struct lttng_bytecode_alloc **bytecode_reloc, + const char *symbol); + static inline unsigned int bytecode_get_len(struct lttng_bytecode *bytecode) { diff --git a/src/common/filter/filter-visitor-generate-bytecode.c b/src/common/filter/filter-visitor-generate-bytecode.c index 51ebad130..e0ba9fd0a 100644 --- a/src/common/filter/filter-visitor-generate-bytecode.c +++ b/src/common/filter/filter-visitor-generate-bytecode.c @@ -240,124 +240,55 @@ int visit_node_load_expression(struct filter_parser_ctx *ctx, switch (op->type) { case IR_LOAD_EXPRESSION_GET_CONTEXT_ROOT: { - struct load_op *insn; - uint32_t insn_len = sizeof(struct load_op); - int ret; + const int ret = bytecode_push_get_context_root(&ctx->bytecode); - insn = calloc(insn_len, 1); - if (!insn) - return -ENOMEM; - insn->op = BYTECODE_OP_GET_CONTEXT_ROOT; - ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len); - free(insn); if (ret) { return ret; } + break; } case IR_LOAD_EXPRESSION_GET_APP_CONTEXT_ROOT: { - struct load_op *insn; - uint32_t insn_len = sizeof(struct load_op); - int ret; + const int ret = bytecode_push_get_app_context_root(&ctx->bytecode); - insn = calloc(insn_len, 1); - if (!insn) - return -ENOMEM; - insn->op = BYTECODE_OP_GET_APP_CONTEXT_ROOT; - ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len); - free(insn); if (ret) { return ret; } + break; } case IR_LOAD_EXPRESSION_GET_PAYLOAD_ROOT: { - struct load_op *insn; - uint32_t insn_len = sizeof(struct load_op); - int ret; + const int ret = bytecode_push_get_payload_root(&ctx->bytecode); - insn = calloc(insn_len, 1); - if (!insn) - return -ENOMEM; - insn->op = BYTECODE_OP_GET_PAYLOAD_ROOT; - ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len); - free(insn); if (ret) { return ret; } + break; } case IR_LOAD_EXPRESSION_GET_SYMBOL: { - struct load_op *insn; - uint32_t insn_len = sizeof(struct load_op) - + sizeof(struct get_symbol); - struct get_symbol symbol_offset; - uint32_t reloc_offset_u32; - uint16_t reloc_offset; - uint32_t bytecode_reloc_offset_u32; - int ret; + const int ret = bytecode_push_get_symbol( + &ctx->bytecode, + &ctx->bytecode_reloc, + op->u.symbol); - insn = calloc(insn_len, 1); - if (!insn) - return -ENOMEM; - insn->op = BYTECODE_OP_GET_SYMBOL; - bytecode_reloc_offset_u32 = - bytecode_get_len(&ctx->bytecode_reloc->b) - + sizeof(reloc_offset); - symbol_offset.offset = - (uint16_t) bytecode_reloc_offset_u32; - memcpy(insn->data, &symbol_offset, - sizeof(symbol_offset)); - /* reloc_offset points to struct load_op */ - 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); - return ret; - } - /* append reloc */ - ret = bytecode_push(&ctx->bytecode_reloc, &reloc_offset, - 1, sizeof(reloc_offset)); - if (ret) { - free(insn); - return ret; - } - ret = bytecode_push(&ctx->bytecode_reloc, - op->u.symbol, - 1, strlen(op->u.symbol) + 1); - free(insn); if (ret) { return ret; } + break; } case IR_LOAD_EXPRESSION_GET_INDEX: { - struct load_op *insn; - uint32_t insn_len = sizeof(struct load_op) - + sizeof(struct get_index_u64); - struct get_index_u64 index; - int ret; + const int ret = bytecode_push_get_index_u64(&ctx->bytecode, op->u.index); - insn = calloc(insn_len, 1); - if (!insn) - return -ENOMEM; - insn->op = BYTECODE_OP_GET_INDEX_U64; - index.index = op->u.index; - memcpy(insn->data, &index, sizeof(index)); - ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len); - free(insn); if (ret) { return ret; } + break; } case IR_LOAD_EXPRESSION_LOAD_FIELD: -- 2.34.1