diff options
author | João Valverde <j@v6e.pt> | 2022-03-20 20:32:39 +0000 |
---|---|---|
committer | João Valverde <j@v6e.pt> | 2022-03-21 17:09:56 +0000 |
commit | d60f2580bafaa4596e5d0ead95646910aa46266c (patch) | |
tree | 73e7449b7ddcaee10016ebee866e323b63da3141 | |
parent | 94d909103e7dcad4ffb94b84abad9fce676c3129 (diff) |
dfilter: Pass around constants in instructions
The DFVM instructions arguments are generic boxed types but instead
of using FVALUE and PCRE types the code passes aroung REGISTER types
instead. Change that to pass constants in the instruction.
-rw-r--r-- | epan/dfilter/dfvm.c | 145 | ||||
-rw-r--r-- | epan/dfilter/dfvm.h | 2 | ||||
-rw-r--r-- | epan/dfilter/gencode.c | 50 |
3 files changed, 56 insertions, 141 deletions
diff --git a/epan/dfilter/dfvm.c b/epan/dfilter/dfvm.c index 31de83c016..b1086ca084 100644 --- a/epan/dfilter/dfvm.c +++ b/epan/dfilter/dfvm.c @@ -309,16 +309,6 @@ dfvm_dump(FILE *f, dfilter_t *df) fprintf(f, "%05d IF_FALSE_GOTO\t%u\n", id, arg1->value.numeric); break; - - case PUT_FVALUE: - fprintf(f, "%05d PUT_FVALUE\t%s -> %s\n", - id, arg1_str, arg2_str); - break; - - case PUT_PCRE: - fprintf(f, "%05d PUT_PCRE \t%s -> %s\n", - id, arg1_str, arg2_str); - break; } g_free(arg1_str); @@ -384,33 +374,6 @@ read_tree(dfilter_t *df, proto_tree *tree, return TRUE; } - -/* Put a constant value in a register. These will not be cleared by - * free_register_overhead. */ -static gboolean -put_fvalue(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *arg2) -{ - fvalue_t *fv = arg1->value.fvalue; - int reg = arg2->value.numeric; - - df->registers[reg] = g_slist_prepend(NULL, fv); - df->owns_memory[reg] = FALSE; - return TRUE; -} - -/* Put a constant PCRE in a register. These will not be cleared by - * free_register_overhead. */ -static gboolean -put_pcre(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *arg2) -{ - ws_regex_t *pcre = arg1->value.pcre; - int reg = arg2->value.numeric; - - df->registers[reg] = g_slist_prepend(NULL, pcre); - df->owns_memory[reg] = FALSE; - return TRUE; -} - enum match_how { MATCH_ANY, MATCH_ALL @@ -420,73 +383,86 @@ typedef gboolean (*DFVMCompareFunc)(const fvalue_t*, const fvalue_t*); static gboolean cmp_test(enum match_how how, DFVMCompareFunc match_func, - GSList *reg1, GSList *reg2) + GSList *arg1, GSList *arg2) { - GSList *list_a, *list_b; + GSList *list1, *list2; gboolean want_all = (how == MATCH_ALL); gboolean want_any = (how == MATCH_ANY); gboolean have_match; - list_a = reg1; + list1 = arg1; - while (list_a) { - list_b = reg2; - while (list_b) { - have_match = match_func(list_a->data, list_b->data); + while (list1) { + list2 = arg2; + while (list2) { + have_match = match_func(list1->data, list2->data); if (want_all && !have_match) { return FALSE; } else if (want_any && have_match) { return TRUE; } - list_b = g_slist_next(list_b); + list2 = g_slist_next(list2); } - list_a = g_slist_next(list_a); + list1 = g_slist_next(list1); } /* want_all || !want_any */ return want_all; } /* cmp(A) <=> cmp(a1) OR cmp(a2) OR cmp(a3) OR ... */ -static inline gboolean +static gboolean any_test(dfilter_t *df, DFVMCompareFunc cmp, dfvm_value_t *arg1, dfvm_value_t *arg2) { - GSList *reg1 = df->registers[arg1->value.numeric]; - GSList *reg2 = df->registers[arg2->value.numeric]; + ws_assert(arg1->type == REGISTER); + GSList *list1 = df->registers[arg1->value.numeric]; - return cmp_test(MATCH_ANY, cmp, reg1, reg2); + if (arg2->type == REGISTER) { + return cmp_test(MATCH_ANY, cmp, list1, df->registers[arg2->value.numeric]); + } + if (arg2->type == FVALUE) { + GSList list2; + + list2.data = arg2->value.fvalue; + list2.next = NULL; + return cmp_test(MATCH_ANY, cmp, list1, &list2); + } + ws_assert_not_reached(); } /* cmp(A) <=> cmp(a1) AND cmp(a2) AND cmp(a3) AND ... */ -static inline gboolean +static gboolean all_test(dfilter_t *df, DFVMCompareFunc cmp, dfvm_value_t *arg1, dfvm_value_t *arg2) { - GSList *reg1 = df->registers[arg1->value.numeric]; - GSList *reg2 = df->registers[arg2->value.numeric]; + ws_assert(arg1->type == REGISTER); + GSList *list1 = df->registers[arg1->value.numeric]; - return cmp_test(MATCH_ALL, cmp, reg1, reg2); + if (arg2->type == REGISTER) { + return cmp_test(MATCH_ALL, cmp, list1, df->registers[arg2->value.numeric]); + } + if (arg2->type == FVALUE) { + GSList list2; + + list2.data = arg2->value.fvalue; + list2.next = NULL; + return cmp_test(MATCH_ALL, cmp, list1, &list2); + } + ws_assert_not_reached(); } static gboolean any_matches(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *arg2) { - GSList *reg1 = df->registers[arg1->value.numeric]; - GSList *reg2 = df->registers[arg2->value.numeric]; - GSList *list_a, *list_b; - - list_a = reg1; + GSList *list1 = df->registers[arg1->value.numeric]; + ws_regex_t *re = arg2->value.pcre; - while (list_a) { - list_b = reg2; - while (list_b) { - if (fvalue_matches(list_a->data, list_b->data)) { - return TRUE; - } - list_b = g_slist_next(list_b); + while (list1) { + if (fvalue_matches(list1->data, re)) { + return TRUE; } - list_a = g_slist_next(list_a); + list1 = g_slist_next(list1); } return FALSE; } @@ -495,27 +471,13 @@ static gboolean any_in_range(dfilter_t *df, dfvm_value_t *arg1, dfvm_value_t *arg_low, dfvm_value_t *arg_high) { - GSList *list1, *list_low, *list_high; - fvalue_t *low, *high, *value; - - list1 = df->registers[arg1->value.numeric]; - list_low = df->registers[arg_low->value.numeric]; - list_high = df->registers[arg_high->value.numeric]; - - /* The first register contains the values associated with a field, the - * second and third arguments are expected to be a single value for the - * lower and upper bound respectively. These cannot be fields and thus - * the list length MUST be one. This should have been enforced by - * grammar.lemon. - */ - ws_assert(list_low && !g_slist_next(list_low)); - ws_assert(list_high && !g_slist_next(list_high)); - low = list_low->data; - high = list_high->data; + GSList *list1 = df->registers[arg1->value.numeric]; + fvalue_t *low = arg_low->value.fvalue; + fvalue_t *high = arg_high->value.fvalue; while (list1) { - value = list1->data; - if (fvalue_ge(value, low) && fvalue_le(value, high)) { + if (fvalue_ge(list1->data, low) && + fvalue_le(list1->data, high)) { return TRUE; } list1 = g_slist_next(list1); @@ -527,8 +489,7 @@ any_in_range(dfilter_t *df, dfvm_value_t *arg1, static void free_owned_register(gpointer data, gpointer user_data _U_) { - fvalue_t *value = (fvalue_t *)data; - fvalue_free(value); + fvalue_free(data); } /* Clear registers that were populated during evaluation. @@ -727,14 +688,6 @@ dfvm_apply(dfilter_t *df, proto_tree *tree) goto AGAIN; } break; - - case PUT_FVALUE: - put_fvalue(df, arg1, arg2); - break; - - case PUT_PCRE: - put_pcre(df, arg1, arg2); - break; } } diff --git a/epan/dfilter/dfvm.h b/epan/dfilter/dfvm.h index 2c391c33a6..673f77f350 100644 --- a/epan/dfilter/dfvm.h +++ b/epan/dfilter/dfvm.h @@ -53,8 +53,6 @@ typedef enum { NOT, RETURN, READ_TREE, - PUT_FVALUE, - PUT_PCRE, ALL_EQ, ANY_EQ, ALL_NE, diff --git a/epan/dfilter/gencode.c b/epan/dfilter/gencode.c index 2584ee06fc..8e02e1d0b9 100644 --- a/epan/dfilter/gencode.c +++ b/epan/dfilter/gencode.c @@ -92,23 +92,6 @@ dfw_append_read_tree(dfwork_t *dfw, header_field_info *hfinfo) /* returns register number */ static dfvm_value_t * -dfw_append_put_fvalue(dfwork_t *dfw, fvalue_t *fv) -{ - dfvm_insn_t *insn; - dfvm_value_t *reg_val, *val1; - - insn = dfvm_insn_new(PUT_FVALUE); - val1 = dfvm_value_new_fvalue(fv); - insn->arg1 = dfvm_value_ref(val1); - reg_val = dfvm_value_new_register(dfw->next_register++); - insn->arg2 = dfvm_value_ref(reg_val); - dfw_append_insn(dfw, insn); - - return reg_val; -} - -/* returns register number */ -static dfvm_value_t * dfw_append_mk_range(dfwork_t *dfw, stnode_t *node, GSList **jumps_ptr) { stnode_t *entity; @@ -183,24 +166,6 @@ dfw_append_function(dfwork_t *dfw, stnode_t *node, GSList **jumps_ptr) return reg_val; } -/* returns register number */ -static dfvm_value_t * -dfw_append_put_pcre(dfwork_t *dfw, ws_regex_t *pcre) -{ - dfvm_insn_t *insn; - dfvm_value_t *reg_val, *val1; - - insn = dfvm_insn_new(PUT_PCRE); - val1 = dfvm_value_new_pcre(pcre); - insn->arg1 = dfvm_value_ref(val1); - reg_val = dfvm_value_new_register(dfw->next_register++); - insn->arg2 = dfvm_value_ref(reg_val); - dfw_append_insn(dfw, insn); - - return reg_val; -} - - /** * Adds an instruction for a relation operator where the values are already * loaded in registers. @@ -323,14 +288,13 @@ gen_entity(dfwork_t *dfw, stnode_t *st_arg, GSList **jumps_ptr) { sttype_id_t e_type; dfvm_insn_t *insn; - dfvm_value_t *jmp; + dfvm_value_t *val, *jmp; header_field_info *hfinfo; - dfvm_value_t *reg_val; e_type = stnode_type_id(st_arg); if (e_type == STTYPE_FIELD) { hfinfo = stnode_data(st_arg); - reg_val = dfw_append_read_tree(dfw, hfinfo); + val = dfw_append_read_tree(dfw, hfinfo); insn = dfvm_insn_new(IF_FALSE_GOTO); jmp = dfvm_value_new(INSN_NUMBER); @@ -339,22 +303,22 @@ gen_entity(dfwork_t *dfw, stnode_t *st_arg, GSList **jumps_ptr) *jumps_ptr = g_slist_prepend(*jumps_ptr, jmp); } else if (e_type == STTYPE_FVALUE) { - reg_val = dfw_append_put_fvalue(dfw, stnode_steal_data(st_arg)); + val = dfvm_value_new_fvalue(stnode_steal_data(st_arg)); } else if (e_type == STTYPE_RANGE) { - reg_val = dfw_append_mk_range(dfw, st_arg, jumps_ptr); + val = dfw_append_mk_range(dfw, st_arg, jumps_ptr); } else if (e_type == STTYPE_FUNCTION) { - reg_val = dfw_append_function(dfw, st_arg, jumps_ptr); + val = dfw_append_function(dfw, st_arg, jumps_ptr); } else if (e_type == STTYPE_PCRE) { - reg_val = dfw_append_put_pcre(dfw, stnode_steal_data(st_arg)); + val = dfvm_value_new_pcre(stnode_steal_data(st_arg)); } else { /* printf("sttype_id is %u\n", (unsigned)e_type); */ ws_assert_not_reached(); } - return reg_val; + return val; } |