{
struct load_op *insn;
uint32_t insn_len = sizeof(struct load_op)
- + strlen(node->u.load.u.string) + 1;
+ + strlen(node->u.load.u.string.value) + 1;
insn = calloc(insn_len, 1);
if (!insn)
return -ENOMEM;
- insn->op = FILTER_OP_LOAD_STRING;
- strcpy(insn->data, node->u.load.u.string);
+
+ switch (node->u.load.u.string.type) {
+ case IR_LOAD_STRING_TYPE_GLOB_STAR:
+ /*
+ * We explicitly tell the interpreter here that
+ * this load is a full star globbing pattern so
+ * that the appropriate matching function can be
+ * called. Also, see comment below.
+ */
+ insn->op = FILTER_OP_LOAD_STAR_GLOB_STRING;
+ break;
+ default:
+ /*
+ * This is the "legacy" string, which includes
+ * star globbing patterns with a star only at
+ * the end. Both "plain" and "star at the end"
+ * literal strings are handled at the same place
+ * by the tracer's filter bytecode interpreter,
+ * whereas full star globbing patterns (stars
+ * can be anywhere in the string) is a special
+ * case.
+ */
+ insn->op = FILTER_OP_LOAD_STRING;
+ break;
+ }
+
+ strcpy(insn->data, node->u.load.u.string.value);
ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len);
free(insn);
return ret;
insn = calloc(insn_len, 1);
if (!insn)
return -ENOMEM;
- switch(node->data_type) {
+ switch (node->data_type) {
case IR_DATA_FIELD_REF:
insn->op = FILTER_OP_LOAD_FIELD_REF;
break;
free(insn);
return ret;
}
+ case IR_DATA_FIELD_REF_INDEX: /* fall-through */
+ case IR_DATA_GET_CONTEXT_REF_INDEX:
+ {
+ struct load_op *insn;
+ uint32_t insn_len = sizeof(struct load_op)
+ + sizeof(struct field_ref_index);
+ struct field_ref_index ref_index_offset;
+ uint32_t reloc_offset_u32;
+ uint16_t reloc_offset;
+
+ insn = calloc(insn_len, 1);
+ if (!insn)
+ return -ENOMEM;
+ switch (node->data_type) {
+ case IR_DATA_FIELD_REF_INDEX:
+ insn->op = FILTER_OP_LOAD_FIELD_REF_INDEX;
+ break;
+ case IR_DATA_GET_CONTEXT_REF_INDEX:
+ insn->op = FILTER_OP_GET_CONTEXT_REF_INDEX;
+ break;
+ default:
+ free(insn);
+ return -EINVAL;
+ }
+ ref_index_offset.offset = (uint16_t) -1U;
+ ref_index_offset.index = node->u.load.u.ref_index.index;
+ memcpy(insn->data, &ref_index_offset, sizeof(ref_index_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, node->u.load.u.ref_index.symbol,
+ 1, strlen(node->u.load.u.ref_index.symbol) + 1);
+ free(insn);
+ return ret;
+ }
}
}
return ret;
/* Cast to s64 if float or 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_GET_CONTEXT_REF
+ || node->u.binary.left->data_type == IR_DATA_FIELD_REF_INDEX
+ || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF_INDEX)
|| 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
- || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF) {
+ || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF
+ || node->u.binary.left->data_type == IR_DATA_FIELD_REF_INDEX
+ || node->u.binary.left->data_type == IR_DATA_GET_CONTEXT_REF_INDEX) {
cast_insn.op = FILTER_OP_CAST_TO_S64;
} else {
cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64;
return ret;
/* Cast to s64 if float or 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_GET_CONTEXT_REF
+ || node->u.binary.right->data_type == IR_DATA_FIELD_REF_INDEX
+ || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF_INDEX)
|| 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
- || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF) {
+ || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF
+ || node->u.binary.right->data_type == IR_DATA_FIELD_REF_INDEX
+ || node->u.binary.right->data_type == IR_DATA_GET_CONTEXT_REF_INDEX) {
cast_insn.op = FILTER_OP_CAST_TO_S64;
} else {
cast_insn.op = FILTER_OP_CAST_DOUBLE_TO_S64;