summaryrefslogtreecommitdiff
path: root/src/analysis/scan/context.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/scan/context.c')
-rw-r--r--src/analysis/scan/context.c168
1 files changed, 144 insertions, 24 deletions
diff --git a/src/analysis/scan/context.c b/src/analysis/scan/context.c
index 9a0e9ac..7929f9c 100644
--- a/src/analysis/scan/context.c
+++ b/src/analysis/scan/context.c
@@ -53,6 +53,13 @@ static void g_scan_context_dispose(GScanContext *);
/* Procède à la libération totale de la mémoire. */
static void g_scan_context_finalize(GScanContext *);
+#ifndef __USE_TABLE_FOR_MATCHES
+
+/* Compare un lien entre motif et correspondances avec un autre. */
+static int compare_matched_pattern(const matched_pattern_t *, const matched_pattern_t *);
+
+#endif
+
/* ---------------------------------------------------------------------------------- */
@@ -107,10 +114,17 @@ static void g_scan_context_init(GScanContext *context)
context->content = NULL;
context->scan_done = false;
+ context->match_allocator = g_umem_slice_new(sizeof(match_area_t));
context->match_storages = NULL;
context->storages_count = 0;
- context->full_trackers = g_hash_table_new_full(NULL, NULL, g_object_unref, g_object_unref);
+#ifdef __USE_TABLE_FOR_MATCHES
+ context->full_trackers = g_hash_table_new_full(NULL, NULL, NULL/*g_object_unref*/, g_object_unref);
+#else
+ context->full_trackers = NULL;
+ context->full_allocated = 0;
+ context->full_count = 0;
+#endif
context->global = true;
@@ -134,19 +148,38 @@ static void g_scan_context_init(GScanContext *context)
static void g_scan_context_dispose(GScanContext *context)
{
- size_t i; /* Boucle de parcours */
+#ifndef __USE_TABLE_FOR_MATCHES
+ matched_pattern_t *iter; /* Boucle de parcours #1 */
+ matched_pattern_t *max; /* Borne de fin de parcours */
+#endif
+ size_t i; /* Boucle de parcours #2 */
g_clear_object(&context->options);
g_clear_object(&context->content);
- for (i = 0; i < context->storages_count; i++)
- g_clear_object(&context->match_storages[i]);
+ g_clear_object(&context->match_allocator);
if (context->full_trackers != NULL)
{
+#ifdef __USE_TABLE_FOR_MATCHES
+
g_hash_table_destroy(context->full_trackers);
context->full_trackers = NULL;
+
+#else
+
+ iter = context->full_trackers;
+ max = iter + context->full_count;
+
+ for (; iter < max; iter++)
+ g_object_unref(G_OBJECT(iter->matches));
+
+ free(context->full_trackers);
+ context->full_trackers = NULL;
+
+#endif
+
}
for (i = 0; i < context->cond_count; i++)
@@ -257,20 +290,15 @@ GScanOptions *g_scan_context_get_options(const GScanContext *context)
void g_scan_context_set_content(GScanContext *context, GBinContent *content, size_t ids_count)
{
- size_t i; /* Boucle de parcours */
-
g_clear_object(&context->content);
context->content = content;
g_object_ref(G_OBJECT(content));
- context->match_storages = calloc(ids_count, sizeof(GUMemSlice *));
+ context->match_storages = calloc(ids_count, sizeof(match_area_t *));
context->storages_count = ids_count;
- for (i = 0; i < ids_count; i++)
- context->match_storages[i] = g_umem_slice_new(sizeof(match_area_t));
-
}
@@ -344,25 +372,26 @@ void g_scan_context_mark_scan_as_done(GScanContext *context)
/******************************************************************************
* *
* Paramètres : context = instance à mettre à jour. *
-* count = nombre d'allocateurs en place. [OUT] *
+* id = identifiant du motif trouvé. *
+* end = position finale d'une correspondance partielle. *
* *
-* Description : Fournit la liste des allocateurs mémorisant des emplacements.*
+* Description : Retourne tous les correspondances partielles notées. *
* *
-* Retour : Liste des allocateurs assurant un suivi des correspondances. *
+* Retour : Liste interne des localisations conservées. *
* *
* Remarques : - *
* *
******************************************************************************/
-GUMemSlice **g_scan_context_get_match_storages(GScanContext *context, size_t *count)
+void g_scan_context_store_atom_match_end(GScanContext *context, patid_t id, phys_t end)
{
- GUMemSlice **result; /* Allocateur à renvoyer */
+ match_area_t *new; /* Nouvel enregistrement */
- result = context->match_storages;
+ new = g_umem_slice_alloc(context->match_allocator);
- *count = context->storages_count;
+ new->end = end + 1;
- return result;
+ add_tail_match_area(new, &context->match_storages[id]);
}
@@ -380,18 +409,46 @@ GUMemSlice **g_scan_context_get_match_storages(GScanContext *context, size_t *co
* *
******************************************************************************/
-GUMemSlice *g_scan_context_get_atom_matches(const GScanContext *context, patid_t id)
+match_area_t *g_scan_context_get_atom_matches(const GScanContext *context, patid_t id)
{
- GUMemSlice *result; /* Liste constituée à renvoyer */
+ match_area_t *result; /* Liste constituée à renvoyer */
result = context->match_storages[id];
- g_object_ref(G_OBJECT(result));
+ return result;
+
+}
+
+
+#ifndef __USE_TABLE_FOR_MATCHES
+
+/******************************************************************************
+* *
+* Paramètres : a = premier lien motif/correspondances à comparer. *
+* b = second lien motif/correspondances à comparer. *
+* *
+* Description : Compare un lien entre motif et correspondances avec un autre.*
+* *
+* Retour : Bilan de la comparaison. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int compare_matched_pattern(const matched_pattern_t *a, const matched_pattern_t *b)
+{
+ int result; /* Bilan à renvoyer */
+
+ assert(sizeof(unsigned long) == sizeof(void *));
+
+ result = sort_unsigned_long((unsigned long)a->pattern, (unsigned long)b->pattern);
return result;
}
+#endif
+
/******************************************************************************
* *
@@ -412,8 +469,9 @@ void g_scan_context_register_full_matches(GScanContext *context, GSearchPattern
#ifndef NDEBUG
GSearchPattern *matches_pattern; /* Clef d'un suivi */
#endif
-
- assert(!g_hash_table_contains(context->full_trackers, pattern));
+#ifndef __USE_TABLE_FOR_MATCHES
+ matched_pattern_t new; /* Nouvel enregistrement */
+#endif
#ifndef NDEBUG
@@ -425,11 +483,28 @@ void g_scan_context_register_full_matches(GScanContext *context, GSearchPattern
#endif
- g_object_ref(G_OBJECT(pattern));
+#ifdef __USE_TABLE_FOR_MATCHES
+
+ assert(!g_hash_table_contains(context->full_trackers, pattern));
+
+ //g_object_ref(G_OBJECT(pattern)); /* TODO : REMME */
g_object_ref(G_OBJECT(matches));
g_hash_table_insert(context->full_trackers, pattern, matches);
+#else
+
+ new.pattern = pattern;
+ new.matches = matches;
+
+ g_object_ref(G_OBJECT(matches));
+
+ context->full_trackers = qinsert_managed(context->full_trackers, &context->full_count, &context->full_allocated,
+ sizeof(matched_pattern_t), (__compar_fn_t)compare_matched_pattern,
+ &new);
+
+#endif
+
g_scan_matches_attach(matches, context, pattern);
}
@@ -451,12 +526,36 @@ void g_scan_context_register_full_matches(GScanContext *context, GSearchPattern
GScanMatches *g_scan_context_get_full_matches(const GScanContext *context, const GSearchPattern *pattern)
{
GScanMatches *result; /* Correspondance à renvoyer */
+#ifndef __USE_TABLE_FOR_MATCHES
+ matched_pattern_t target; /* Lien ciblé */
+ matched_pattern_t *found; /* Lien trouvé */
+#endif
+
+#ifdef __USE_TABLE_FOR_MATCHES
result = g_hash_table_lookup(context->full_trackers, pattern);
if (result != NULL)
g_object_ref(G_OBJECT(result));
+#else
+
+ target.pattern = pattern;
+
+ found = bsearch(&target, context->full_trackers, context->full_count,
+ sizeof(matched_pattern_t), (__compar_fn_t)compare_matched_pattern);
+
+ if (found == NULL)
+ result = NULL;
+
+ else
+ {
+ result = found->matches;
+ g_object_ref(G_OBJECT(result));
+ }
+
+#endif
+
return result;
}
@@ -478,7 +577,14 @@ GScanMatches *g_scan_context_get_full_matches(const GScanContext *context, const
size_t g_scan_context_count_full_matches(const GScanContext *context, const GSearchPattern *pattern)
{
size_t result; /* Quantité à retourner */
+#ifdef __USE_TABLE_FOR_MATCHES
GScanMatches *matches; /* Ensemble de Correspondances */
+#else
+ matched_pattern_t target; /* Lien ciblé */
+ matched_pattern_t *found; /* Lien trouvé */
+#endif
+
+#ifdef __USE_TABLE_FOR_MATCHES
matches = g_hash_table_lookup(context->full_trackers, pattern);
@@ -487,6 +593,20 @@ size_t g_scan_context_count_full_matches(const GScanContext *context, const GSea
else
result = 0;
+#else
+
+ target.pattern = pattern;
+
+ found = bsearch(&target, context->full_trackers, context->full_count,
+ sizeof(matched_pattern_t), (__compar_fn_t)compare_matched_pattern);
+
+ if (found == NULL)
+ result = 0;
+ else
+ result = g_scan_matches_count(found->matches);
+
+#endif
+
return result;
}