diff options
Diffstat (limited to 'src/analysis/scan/matches')
-rw-r--r-- | src/analysis/scan/matches/pending.c | 279 | ||||
-rw-r--r-- | src/analysis/scan/matches/pending.h | 36 |
2 files changed, 263 insertions, 52 deletions
diff --git a/src/analysis/scan/matches/pending.c b/src/analysis/scan/matches/pending.c index 9d1037d..03cf3f2 100644 --- a/src/analysis/scan/matches/pending.c +++ b/src/analysis/scan/matches/pending.c @@ -24,18 +24,80 @@ #include "pending.h" -#include <assert.h> #include <malloc.h> +#include <stdlib.h> #include <string.h> +#include "../../../common/sort.h" + + + +/* ------------------------- MEMORISATION D'UNE ZONE BORNEE ------------------------- */ + + +/* Compare deux couvertures bornées de correspondances. */ +static int compare_match_area(const match_area_t *, const match_area_t *); + + + +/* -------------------- CONSERVATION DE CORRESPONDANCES ETABLIES -------------------- */ + + #define PENDING_ALLOC_SIZE 10 + + + + +/* ---------------------------------------------------------------------------------- */ +/* MEMORISATION D'UNE ZONE BORNEE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = pointeur vers la première zone à analyser. * +* b = pointeur vers la seconde zone à analyser. * +* * +* Description : Compare deux couvertures bornées de correspondances. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int compare_match_area(const match_area_t *a, const match_area_t *b) +{ + int result; /* Bilan à renvoyer */ + + result = sort_unsigned_long_long(a->start, b->start); + + if (result == 0) + result = sort_unsigned_long_long(a->end, b->end); + + if (result == 0) + result = sort_unsigned_long_long(a->ttl, b->ttl); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* CONSERVATION DE CORRESPONDANCES ETABLIES */ +/* ---------------------------------------------------------------------------------- */ + + /****************************************************************************** * * * Paramètres : matches = suivi de correspondances à initialiser. * +* start = première position du contenu (souvent 0). * +* end = position de fin du contenu. * * * * Description : Initialise une structure de consolidation de correspondances.* * * @@ -45,14 +107,84 @@ * * ******************************************************************************/ -void init_pending_matches(pending_matches_t *matches) +void init_pending_matches(pending_matches_t *matches, const phys_t *start, const phys_t *end) { + matches->content_start = *start; + matches->content_end = *end; + matches->areas = NULL; matches->allocated = 0; matches->used = 0; matches->initialized = false; + matches->abort = false; + +} + + +/****************************************************************************** +* * +* Paramètres : dest = suivi de correspondances à initialiser. [OUT] * +* src = suivi de correspondances à copier. * +* * +* Description : Copie une structure de consolidation de correspondances. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void copy_pending_matches(pending_matches_t *dest, const pending_matches_t *src) +{ + dest->content_start = src->content_start; + dest->content_end = src->content_end; + + dest->areas = malloc(src->used * sizeof(match_area_t)); + dest->allocated = src->used; + dest->used = src->used; + + memcpy(dest->areas, src->areas, src->used * sizeof(match_area_t)); + + dest->initialized = src->initialized; + + dest->abort = src->abort; + +} + + +/****************************************************************************** +* * +* Paramètres : dest = suivi de correspondances à initialiser. [OUT] * +* src = suivi de correspondances à copier. * +* * +* Description : Fusionne une structure de consolidation avec une autre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void merge_pending_matches(pending_matches_t *dest, const pending_matches_t *src) +{ + if ((dest->used + src->used) > dest->allocated) + { + dest->allocated += src->used; + + dest->areas = realloc(dest->areas, dest->allocated * sizeof(match_area_t)); + + } + + memcpy(&dest->areas[dest->used], src->areas, src->used * sizeof(match_area_t)); + + dest->used += src->used; + + dest->initialized |= src->initialized; + + dest->abort |= src->abort; + } @@ -112,11 +244,11 @@ size_t count_pending_matches(const pending_matches_t *matches) * * ******************************************************************************/ -const match_area_t *get_all_pending_matches(const pending_matches_t *matches, size_t *count) +match_area_t * const *get_all_pending_matches(const pending_matches_t *matches, size_t *count) { - match_area_t *result; /* Série à renvoyer */ + match_area_t * const *result; /* Série à renvoyer */ - result = matches->areas; + result = &matches->areas; *count = matches->used; @@ -156,8 +288,15 @@ void add_pending_match(pending_matches_t *matches, phys_t start, phys_t length) area->start = start; area->end = start + length; + assert(matches->content_start <= area->start); + assert(area->end <= matches->content_end); + area->ttl = 1; + printf("[i] new match: from %llx to %llx\n", + (unsigned long long)area->start, + (unsigned long long)area->end); + } @@ -165,7 +304,7 @@ void add_pending_match(pending_matches_t *matches, phys_t start, phys_t length) * * * Paramètres : matches = suivi de correspondances à compléter. * * target = indice de la zone de correspondance concernée. * -* length = taille de la zone couverte supplémentaire. * +* start = nouvelle position initiale de la zone couverte. * * * * Description : Etend une zone couverte dans le suivi des correspondances. * * * @@ -175,17 +314,19 @@ void add_pending_match(pending_matches_t *matches, phys_t start, phys_t length) * * ******************************************************************************/ -void extend_pending_match(pending_matches_t *matches, size_t target, phys_t end) +void extend_pending_match_beginning(pending_matches_t *matches, size_t target, phys_t start) { match_area_t *area; /* Zone à actualiser */ assert(target < matches->used); - area = &matches->areas[matches->used++]; + area = &matches->areas[target]; if (area->ttl == 0) { - area->end = end; + assert(matches->content_start <= start); + + area->start = start; area->ttl = 1; @@ -194,7 +335,7 @@ void extend_pending_match(pending_matches_t *matches, size_t target, phys_t end) { assert(area->ttl == 1); - add_pending_match(matches, area->start, end - area->start); + add_pending_match(matches, start, area->end - start); } @@ -203,11 +344,11 @@ void extend_pending_match(pending_matches_t *matches, size_t target, phys_t end) /****************************************************************************** * * -* Paramètres : matches = suivi de correspondances à consulter. * +* Paramètres : matches = suivi de correspondances à compléter. * * target = indice de la zone de correspondance concernée. * -* pos = position à tester. * +* length = taille de la zone couverte supplémentaire. * * * -* Description : Détermine si une correspondance se termine à une position. * +* Description : Etend une zone couverte dans le suivi des correspondances. * * * * Retour : - * * * @@ -215,50 +356,40 @@ void extend_pending_match(pending_matches_t *matches, size_t target, phys_t end) * * ******************************************************************************/ -bool has_pending_match_ending_at(const pending_matches_t *matches, size_t target, phys_t pos) +void extend_pending_match_ending(pending_matches_t *matches, size_t target, phys_t end) { - bool result; /* Statut à retourner */ - match_area_t *area; /* Couverture visée */ + match_area_t *area; /* Zone à actualiser */ assert(target < matches->used); area = &matches->areas[target]; - result = (area->end == pos); - - return result; - -} + if (area->ttl == 0) + { + assert(end <= matches->content_end); + printf(" -- extend same (%llu - %llu) -> new end: %llu\n", + (unsigned long long)area->start, + (unsigned long long)area->end, + (unsigned long long)end); -/****************************************************************************** -* * -* Paramètres : matches = suivi de correspondances à consulter. * -* target = indice de la zone de correspondance concernée. * -* pos = position à tester. * -* min = borne inférieure de l'espace à considérer. * -* max = borne supérieure de l'espace à considérer. * -* * -* Description : Détermine si une correspondance se situe dans une plage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + area->end = end; -bool has_pending_match_ending_between(const pending_matches_t *matches, size_t target, phys_t pos, phys_t min, phys_t max) -{ - bool result; /* Statut à retourner */ - match_area_t *area; /* Couverture visée */ + area->ttl = 1; - assert(target < matches->used); + } + else + { + assert(area->ttl == 1); - area = &matches->areas[target]; + printf(" -- extend (%llu - %llu) -> new end: %llu\n", + (unsigned long long)area->start, + (unsigned long long)area->end, + (unsigned long long)end); - result = ((area->end + min) <= pos && pos <= (area->end + max)); + add_pending_match(matches, area->start, end - area->start); - return result; + } } @@ -279,6 +410,8 @@ void reset_pending_matches_ttl(pending_matches_t *matches) { size_t i; /* Boucle de parcours */ + assert(matches->initialized); + for (i = 0; i < matches->used; i++) matches->areas[i].ttl = 0; @@ -305,6 +438,8 @@ void purge_pending_matches(pending_matches_t *matches) size_t del_count; /* Nombre d'éléments à effacer */ size_t i; /* Boucle de parcours */ + assert(matches->initialized); + /** * Note : le code original était le suivant : * @@ -378,4 +513,60 @@ void purge_pending_matches(pending_matches_t *matches) } + /* Bilan */ + + matches->abort = (matches->used == 0); + +} + + +/****************************************************************************** +* * +* Paramètres : matches = suivi de correspondances à finaliser. * +* * +* Description : Trie les correspondances et retire tous les doublons. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void sort_and_filter_pending_matches(pending_matches_t *matches) +{ + match_area_t *last; /* Dernière zone conservée */ + size_t i; /* Boucle de parcours */ + match_area_t *cur; /* Zone courante dans l'analyse*/ + + if (matches->used > 0) + { + qsort(matches->areas, matches->used, sizeof(match_area_t), (__compar_fn_t)compare_match_area); + + last = &matches->areas[0]; + + for (i = 1; i < matches->used; i++) + { + cur = &matches->areas[i]; + + if (last->start != cur->start || last->end != cur->end) + { + if ((cur - last) > 1) + { + memmove(last + 1, cur, (matches->used - i) * sizeof(match_area_t)); + matches->used -= (cur - last + 1); + } + + last = cur; + + } + + } + + cur = &matches->areas[matches->used - 1]; + + if (last != cur) + matches->used = last - matches->areas + 1; + + } + } diff --git a/src/analysis/scan/matches/pending.h b/src/analysis/scan/matches/pending.h index 0a1fe5c..6df01c9 100644 --- a/src/analysis/scan/matches/pending.h +++ b/src/analysis/scan/matches/pending.h @@ -25,6 +25,7 @@ #define _ANALYSIS_SCAN_MATCHES_PENDING_H +#include <assert.h> #include <stdbool.h> @@ -45,17 +46,28 @@ typedef struct _match_area_t /* Suivi de correspondances */ typedef struct _pending_matches_t { + phys_t content_start; /* Point de début du contenu */ + phys_t content_end; /* Point de fin du contenu */ + match_area_t *areas; /* Zones couvertes */ size_t allocated; /* Nombre d'allocations */ size_t used; /* Nombre de zones */ bool initialized; /* Etat du suivi */ + bool abort; /* Inutilité d'une poursuite */ + } pending_matches_t; /* Initialise une structure de consolidation de correspondances. */ -void init_pending_matches(pending_matches_t *); +void init_pending_matches(pending_matches_t *, const phys_t *, const phys_t *); + +/* Copie une structure de consolidation de correspondances. */ +void copy_pending_matches(pending_matches_t *, const pending_matches_t *); + +/* Fusionner une structure de consolidation avec une autre. */ +void merge_pending_matches(pending_matches_t *, const pending_matches_t *); /* Libère la mémoire utilisée par une consolidation. */ void exit_pending_matches(pending_matches_t *); @@ -69,26 +81,34 @@ void exit_pending_matches(pending_matches_t *); size_t count_pending_matches(const pending_matches_t *); /* Fournit la liste des correspondances établies à présent. */ -const match_area_t *get_all_pending_matches(const pending_matches_t *, size_t *); +match_area_t * const *get_all_pending_matches(const pending_matches_t *, size_t *); /* Ajoute au suivi la définition d'une nouvelle correspondance. */ void add_pending_match(pending_matches_t *, phys_t, phys_t); /* Etend une zone couverte dans le suivi des correspondances. */ -void extend_pending_match(pending_matches_t *, size_t, phys_t); +void extend_pending_match_beginning(pending_matches_t *, size_t, phys_t); -/* Détermine si une correspondance se situe dans une plage. */ -bool has_pending_match_ending_between(const pending_matches_t *, size_t, phys_t, phys_t, phys_t); - -/* Détermine si une correspondance se termine à une position. */ -bool has_pending_match_ending_at(const pending_matches_t *, size_t, phys_t); +/* Etend une zone couverte dans le suivi des correspondances. */ +void extend_pending_match_ending(pending_matches_t *, size_t, phys_t); /* Réinitialisation à 0 tous les TTL de correspondances. */ void reset_pending_matches_ttl(pending_matches_t *); +#define keep_pending_match(p) \ + do \ + { \ + assert(p->ttl == 0); \ + p->ttl = 1; \ + } \ + while (0); + /* Retire toutes les correspondances sans issue pour l'analyse. */ void purge_pending_matches(pending_matches_t *); +/* Trie les correspondances et retire tous les doublons. */ +void sort_and_filter_pending_matches(pending_matches_t *); + #endif /* _ANALYSIS_SCAN_MATCHES_PENDING_H */ |