X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=lttng-filter-interpreter.c;fp=lttng-filter-interpreter.c;h=a09b04175af0c6dc996d297c7bf0af5d93392858;hb=02aca19338c57e5a26d11faedf031b90eaf4899c;hp=761926f748457e09752eec3b5160dccf0fe2d66a;hpb=231b5333103e13e81c22caa5dc9410ac688c538d;p=lttng-modules.git diff --git a/lttng-filter-interpreter.c b/lttng-filter-interpreter.c index 761926f7..a09b0417 100644 --- a/lttng-filter-interpreter.c +++ b/lttng-filter-interpreter.c @@ -28,6 +28,7 @@ #include #include +#include LTTNG_STACK_FRAME_NON_STANDARD(lttng_filter_interpret_bytecode); @@ -85,6 +86,49 @@ int parse_char(struct estack_entry *reg, char *c, size_t *offset) } } +static +char get_char_at_cb(size_t at, void *data) +{ + return get_char(data, at); +} + +static +int stack_star_glob_match(struct estack *stack, int top, const char *cmp_type) +{ + bool has_user = false; + mm_segment_t old_fs; + int result; + struct estack_entry *pattern_reg; + struct estack_entry *candidate_reg; + + if (estack_bx(stack, top)->u.s.user + || estack_ax(stack, top)->u.s.user) { + has_user = true; + old_fs = get_fs(); + set_fs(KERNEL_DS); + pagefault_disable(); + } + + /* Find out which side is the pattern vs. the candidate. */ + if (estack_ax(stack, top)->u.s.literal_type == ESTACK_STRING_LITERAL_TYPE_STAR_GLOB) { + pattern_reg = estack_ax(stack, top); + candidate_reg = estack_bx(stack, top); + } else { + pattern_reg = estack_bx(stack, top); + candidate_reg = estack_ax(stack, top); + } + + /* Perform the match operation. */ + result = !strutils_star_glob_match_char_cb(get_char_at_cb, + pattern_reg, get_char_at_cb, candidate_reg); + if (has_user) { + pagefault_enable(); + set_fs(old_fs); + } + + return result; +} + static int stack_strcmp(struct estack *stack, int top, const char *cmp_type) { @@ -113,7 +157,8 @@ int stack_strcmp(struct estack *stack, int top, const char *cmp_type) diff = 0; break; } else { - if (estack_ax(stack, top)->u.s.literal) { + if (estack_ax(stack, top)->u.s.literal_type == + ESTACK_STRING_LITERAL_TYPE_PLAIN) { ret = parse_char(estack_ax(stack, top), &char_ax, &offset_ax); if (ret == -1) { @@ -126,7 +171,8 @@ int stack_strcmp(struct estack *stack, int top, const char *cmp_type) } } if (unlikely(char_ax == '\0')) { - if (estack_bx(stack, top)->u.s.literal) { + if (estack_bx(stack, top)->u.s.literal_type == + ESTACK_STRING_LITERAL_TYPE_PLAIN) { ret = parse_char(estack_bx(stack, top), &char_bx, &offset_bx); if (ret == -1) { @@ -137,7 +183,8 @@ int stack_strcmp(struct estack *stack, int top, const char *cmp_type) diff = 1; break; } - if (estack_bx(stack, top)->u.s.literal) { + if (estack_bx(stack, top)->u.s.literal_type == + ESTACK_STRING_LITERAL_TYPE_PLAIN) { ret = parse_char(estack_bx(stack, top), &char_bx, &offset_bx); if (ret == -1) { @@ -148,7 +195,8 @@ int stack_strcmp(struct estack *stack, int top, const char *cmp_type) } /* else compare both char */ } - if (estack_ax(stack, top)->u.s.literal) { + if (estack_ax(stack, top)->u.s.literal_type == + ESTACK_STRING_LITERAL_TYPE_PLAIN) { ret = parse_char(estack_ax(stack, top), &char_ax, &offset_ax); if (ret == -1) { @@ -288,6 +336,10 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data, [ FILTER_OP_GE_STRING ] = &&LABEL_FILTER_OP_GE_STRING, [ FILTER_OP_LE_STRING ] = &&LABEL_FILTER_OP_LE_STRING, + /* globbing pattern binary comparator */ + [ FILTER_OP_EQ_STAR_GLOB_STRING ] = &&LABEL_FILTER_OP_EQ_STAR_GLOB_STRING, + [ FILTER_OP_NE_STAR_GLOB_STRING ] = &&LABEL_FILTER_OP_NE_STAR_GLOB_STRING, + /* s64 binary comparator */ [ FILTER_OP_EQ_S64 ] = &&LABEL_FILTER_OP_EQ_S64, [ FILTER_OP_NE_S64 ] = &&LABEL_FILTER_OP_NE_S64, @@ -343,6 +395,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data, /* load from immediate operand */ [ FILTER_OP_LOAD_STRING ] = &&LABEL_FILTER_OP_LOAD_STRING, + [ FILTER_OP_LOAD_STAR_GLOB_STRING ] = &&LABEL_FILTER_OP_LOAD_STAR_GLOB_STRING, [ FILTER_OP_LOAD_S64 ] = &&LABEL_FILTER_OP_LOAD_S64, [ FILTER_OP_LOAD_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_DOUBLE, @@ -470,6 +523,27 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data, PO; } + OP(FILTER_OP_EQ_STAR_GLOB_STRING): + { + int res; + + res = (stack_star_glob_match(stack, top, "==") == 0); + estack_pop(stack, top, ax, bx); + estack_ax_v = res; + next_pc += sizeof(struct binary_op); + PO; + } + OP(FILTER_OP_NE_STAR_GLOB_STRING): + { + int res; + + res = (stack_star_glob_match(stack, top, "!=") != 0); + estack_pop(stack, top, ax, bx); + estack_ax_v = res; + next_pc += sizeof(struct binary_op); + PO; + } + OP(FILTER_OP_EQ_S64): { int res; @@ -653,7 +727,8 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data, goto end; } estack_ax(stack, top)->u.s.seq_len = UINT_MAX; - estack_ax(stack, top)->u.s.literal = 0; + estack_ax(stack, top)->u.s.literal_type = + ESTACK_STRING_LITERAL_TYPE_NONE; estack_ax(stack, top)->u.s.user = 0; dbg_printk("ref load string %s\n", estack_ax(stack, top)->u.s.str); next_pc += sizeof(struct load_op) + sizeof(struct field_ref); @@ -678,7 +753,8 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data, ret = -EINVAL; goto end; } - estack_ax(stack, top)->u.s.literal = 0; + estack_ax(stack, top)->u.s.literal_type = + ESTACK_STRING_LITERAL_TYPE_NONE; estack_ax(stack, top)->u.s.user = 0; next_pc += sizeof(struct load_op) + sizeof(struct field_ref); PO; @@ -715,7 +791,23 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data, estack_push(stack, top, ax, bx); estack_ax(stack, top)->u.s.str = insn->data; estack_ax(stack, top)->u.s.seq_len = UINT_MAX; - estack_ax(stack, top)->u.s.literal = 1; + estack_ax(stack, top)->u.s.literal_type = + ESTACK_STRING_LITERAL_TYPE_PLAIN; + estack_ax(stack, top)->u.s.user = 0; + next_pc += sizeof(struct load_op) + strlen(insn->data) + 1; + PO; + } + + OP(FILTER_OP_LOAD_STAR_GLOB_STRING): + { + struct load_op *insn = (struct load_op *) pc; + + dbg_printk("load globbing pattern %s\n", insn->data); + estack_push(stack, top, ax, bx); + estack_ax(stack, top)->u.s.str = insn->data; + estack_ax(stack, top)->u.s.seq_len = UINT_MAX; + estack_ax(stack, top)->u.s.literal_type = + ESTACK_STRING_LITERAL_TYPE_STAR_GLOB; estack_ax(stack, top)->u.s.user = 0; next_pc += sizeof(struct load_op) + strlen(insn->data) + 1; PO; @@ -779,7 +871,8 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data, goto end; } estack_ax(stack, top)->u.s.seq_len = UINT_MAX; - estack_ax(stack, top)->u.s.literal = 0; + estack_ax(stack, top)->u.s.literal_type = + ESTACK_STRING_LITERAL_TYPE_NONE; estack_ax(stack, top)->u.s.user = 0; dbg_printk("ref get context string %s\n", estack_ax(stack, top)->u.s.str); next_pc += sizeof(struct load_op) + sizeof(struct field_ref); @@ -828,7 +921,8 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data, goto end; } estack_ax(stack, top)->u.s.seq_len = UINT_MAX; - estack_ax(stack, top)->u.s.literal = 0; + estack_ax(stack, top)->u.s.literal_type = + ESTACK_STRING_LITERAL_TYPE_NONE; estack_ax(stack, top)->u.s.user = 1; dbg_printk("ref load string %s\n", estack_ax(stack, top)->u.s.str); next_pc += sizeof(struct load_op) + sizeof(struct field_ref); @@ -853,7 +947,8 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data, ret = -EINVAL; goto end; } - estack_ax(stack, top)->u.s.literal = 0; + estack_ax(stack, top)->u.s.literal_type = + ESTACK_STRING_LITERAL_TYPE_NONE; estack_ax(stack, top)->u.s.user = 1; next_pc += sizeof(struct load_op) + sizeof(struct field_ref); PO;