aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Valverde <j@v6e.pt>2022-03-20 20:32:39 +0000
committerJoão Valverde <j@v6e.pt>2022-03-21 17:09:56 +0000
commitd60f2580bafaa4596e5d0ead95646910aa46266c (patch)
tree73e7449b7ddcaee10016ebee866e323b63da3141
parent94d909103e7dcad4ffb94b84abad9fce676c3129 (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.c145
-rw-r--r--epan/dfilter/dfvm.h2
-rw-r--r--epan/dfilter/gencode.c50
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;
}