summaryrefslogtreecommitdiff
path: root/src/analysis/block.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/block.c')
-rw-r--r--src/analysis/block.c837
1 files changed, 777 insertions, 60 deletions
diff --git a/src/analysis/block.c b/src/analysis/block.c
index cd3ef94..14b2c0e 100644
--- a/src/analysis/block.c
+++ b/src/analysis/block.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * block.c - encadrement des instructions par blocs
+ * block.h - encadrement des blocs de code
*
* Copyright (C) 2012-2017 Cyrille Bagard
*
@@ -24,33 +24,86 @@
#include "block.h"
+#include <assert.h>
+#include <malloc.h>
+
+
#include "block-int.h"
-/* Initialise la classe des blocs d'instructions. */
-static void g_instr_block_class_init(GInstrBlockClass *);
+/* ----------------------------- BLOC DE CODE GENERIQUE ----------------------------- */
+
+
+/* Initialise la classe des blocs de code. */
+static void g_code_block_class_init(GCodeBlockClass *);
-/* Initialise un bloc d'instructions. */
-static void g_instr_block_init(GInstrBlock *);
+/* Initialise un bloc de code. */
+static void g_code_block_init(GCodeBlock *);
/* Supprime toutes les références externes. */
-static void g_instr_block_dispose(GInstrBlock *);
+static void g_code_block_dispose(GCodeBlock *);
/* Procède à la libération totale de la mémoire. */
-static void g_instr_block_finalize(GInstrBlock *);
+static void g_code_block_finalize(GCodeBlock *);
+
+/* Indique l'indice d'intégration du bloc dans une liste. */
+static void g_code_block_set_index(GCodeBlock *, size_t);
+
+/* Etablit les liens entre un bloc de code et ses voisins. */
+static void g_code_block_resolve_links(GCodeBlock *, const GBlockList *);
+
+/* ------------------------- REGROUPEMENT EN LISTE DE BLOCS ------------------------- */
+
+
+/* Description d'une liste de blocs de code (instance) */
+struct _GBlockList
+{
+ GObject parent; /* A laisser en premier */
+
+ GCodeBlock **blocks; /* Blocs de code rassemblés */
+ size_t count; /* Quantité de ces blocs */
+
+};
+
+/* Description d'une liste de blocs de code (classe) */
+struct _GBlockListClass
+{
+ GObjectClass parent; /* A laisser en premier */
-/* Indique le type défini pour un bloc d'instructions. */
-G_DEFINE_TYPE(GInstrBlock, g_instr_block, G_TYPE_OBJECT);
+};
+
+
+/* Initialise la classe des listes de blocs de code. */
+static void g_block_list_class_init(GBlockListClass *);
+
+/* Initialise une liste de blocs de code. */
+static void g_block_list_init(GBlockList *);
+
+/* Supprime toutes les références externes. */
+static void g_block_list_dispose(GBlockList *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_block_list_finalize(GBlockList *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* BLOC DE CODE GENERIQUE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un bloc de code. */
+G_DEFINE_TYPE(GCodeBlock, g_code_block, G_TYPE_OBJECT);
/******************************************************************************
* *
* Paramètres : class = classe à initialiser. *
* *
-* Description : Initialise la classe des blocs d'instructions. *
+* Description : Initialise la classe des blocs de code. *
* *
* Retour : - *
* *
@@ -58,14 +111,14 @@ G_DEFINE_TYPE(GInstrBlock, g_instr_block, G_TYPE_OBJECT);
* *
******************************************************************************/
-static void g_instr_block_class_init(GInstrBlockClass *class)
+static void g_code_block_class_init(GCodeBlockClass *class)
{
GObjectClass *object; /* Autre version de la classe */
object = G_OBJECT_CLASS(class);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_instr_block_dispose;
- object->finalize = (GObjectFinalizeFunc)g_instr_block_finalize;
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_code_block_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_code_block_finalize;
}
@@ -74,7 +127,7 @@ static void g_instr_block_class_init(GInstrBlockClass *class)
* *
* Paramètres : block = instance à initialiser. *
* *
-* Description : Initialise un bloc d'instructions. *
+* Description : Initialise un bloc de code. *
* *
* Retour : - *
* *
@@ -82,8 +135,15 @@ static void g_instr_block_class_init(GInstrBlockClass *class)
* *
******************************************************************************/
-static void g_instr_block_init(GInstrBlock *block)
+static void g_code_block_init(GCodeBlock *block)
{
+ block->index = (size_t)-1;
+ block->rank = (size_t)-1;
+
+ block->from = NULL;
+ block->to = NULL;
+
+ block->view = NULL;
}
@@ -100,12 +160,24 @@ static void g_instr_block_init(GInstrBlock *block)
* *
******************************************************************************/
-static void g_instr_block_dispose(GInstrBlock *block)
+static void g_code_block_dispose(GCodeBlock *block)
{
- if (block->links_block != NULL)
- g_object_unref(G_OBJECT(block->links_block));
+#ifndef NDEBUG
+ g_code_block_lock_src(block);
+ assert(count_flat_array_items(block->from) == 0);
+ g_code_block_unlock_src(block);
+#endif
+
+#ifndef NDEBUG
+ g_code_block_lock_dest(block);
+ assert(count_flat_array_items(block->to) == 0);
+ g_code_block_unlock_dest(block);
+#endif
- G_OBJECT_CLASS(g_instr_block_parent_class)->dispose(G_OBJECT(block));
+ if (block->view != NULL)
+ g_object_unref(G_OBJECT(block->view));
+
+ G_OBJECT_CLASS(g_code_block_parent_class)->dispose(G_OBJECT(block));
}
@@ -122,62 +194,512 @@ static void g_instr_block_dispose(GInstrBlock *block)
* *
******************************************************************************/
-static void g_instr_block_finalize(GInstrBlock *block)
+static void g_code_block_finalize(GCodeBlock *block)
+{
+ delete_bit_field(block->domination);
+
+ G_OBJECT_CLASS(g_code_block_parent_class)->finalize(G_OBJECT(block));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc de code à consulter. *
+* *
+* Description : Indique la liste des blocs de code dominés. *
+* *
+* Retour : Champ de bits représentant des blocs. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const bitfield_t *g_code_block_get_domination(const GCodeBlock *block)
+{
+ return block->domination;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc à mettre à jour. *
+* index = indice valide dans la liste d'appartenance. *
+* *
+* Description : Indique l'indice d'intégration du bloc dans une liste. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_code_block_set_index(GCodeBlock *block, size_t index)
+{
+ assert(block->index == (size_t)-1);
+
+ block->index = index;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc à consulter. *
+* *
+* Description : Indique l'indice d'intégration du bloc dans une liste. *
+* *
+* Retour : Indice valide dans une liste. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_code_block_get_index(const GCodeBlock *block)
+{
+ size_t result; /* Indice à retourner */
+
+ assert(block->index != (size_t)-1);
+
+ result = block->index;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc de code à consulter. *
+* addr = localisation à comparer. *
+* *
+* Description : Détermine si un bloc de code débute à une adresse donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_code_block_is_starting_with(const GCodeBlock *block, const vmpa2t *addr)
+{
+ bool result; /* Bilan à retourner */
+ GCodeBlockClass *class; /* Classe des blocs de code */
+
+ class = G_CODE_BLOCK_GET_CLASS(block);
+
+ result = class->is_starting(block, addr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc de code à mettre à jour. *
+* list = ensemble des blocs de code à disposition. *
+* *
+* Description : Etablit les liens entre un bloc de code et ses voisins. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_code_block_resolve_links(GCodeBlock *block, const GBlockList *list)
+{
+ GCodeBlockClass *class; /* Classe des blocs de code */
+
+ class = G_CODE_BLOCK_GET_CLASS(block);
+
+ class->link(block, list);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc de code à consulter. *
+* *
+* Description : Fournit le rang du bloc de code dans le flot d'exécution. *
+* *
+* Retour : Indice supérieur ou égal à zéro. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_code_block_get_rank(const GCodeBlock *block)
+{
+ size_t result; /* Rang à retourner */
+
+ result = block->rank;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc de code à mettre à jour. *
+* rank = indice supérieur à zéro à prendre en compte. *
+* *
+* Description : Définit le rang du bloc de code dans le flot d'exécution. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_code_block_set_rank(GCodeBlock *block, size_t rank)
+{
+ block->rank = rank;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc de code à manipuler. *
+* highlighted = gestionnaire de surbrillance pour segments. *
+* *
+* Description : Fournit la représentation graphique d'un bloc de code. *
+* *
+* Retour : Vue d'un cache de lignes. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferView *g_code_block_get_view(GCodeBlock *block, segcnt_list *highlighted)
+{
+ GBufferView *result; /* Instance à retourner */
+ GCodeBlockClass *class; /* Classe des blocs de code */
+
+ if (block->view == NULL)
+ {
+ class = G_CODE_BLOCK_GET_CLASS(block);
+
+ block->view = class->build(block, highlighted);
+
+ }
+
+ result = block->view;
+
+ g_object_ref(G_OBJECT(result));
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION DE LIAISONS ENTRE BLOCS DE CODE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc de code à mettre à jour. *
+* src = sélection de l'extrémité à traiter. *
+* lock = indique le sens du verrouillage à mener. *
+* *
+* Description : Met à disposition un encadrement des accès aux liens. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_code_block_lock_unlock_links(GCodeBlock *block, bool src, bool lock)
+{
+ flat_array_t **array; /* Choix du tableau ciblé */
+
+ array = (src ? &block->from : &block->to);
+
+ if (lock)
+ lock_flat_array(array);
+ else
+ unlock_flat_array(array);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc dont les informations sont à consulter. *
+* dest = bloc de code visé par la liaison (côté destination). *
+* type = type de lien à construire. *
+* *
+* Description : Etablit un lien entre deux blocs de code. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_code_block_link_with(GCodeBlock *block, GCodeBlock *dest, InstructionLinkType type)
+{
+ block_link_t new_src; /* Nouveau lien à définir #1 */
+ block_link_t new_dst; /* Nouveau lien à définir #2 */
+
+ /* Côté destination */
+
+ new_src.linked = block;
+ new_src.type = type;
+
+ ref_block_link((&new_src));
+
+ /* Côté point de départ */
+
+ new_dst.linked = dest;
+ new_dst.type = type;
+
+ ref_block_link((&new_dst));
+
+ /* Ajout dans le respect d'une cohérence globale */
+
+ g_code_block_lock_src(dest);
+ g_code_block_lock_dest(block);
+
+ add_item_to_flat_array(&dest->from, &new_src, sizeof(block_link_t));
+
+ add_item_to_flat_array(&block->to, &new_dst, sizeof(block_link_t));
+
+ g_code_block_unlock_dest(block);
+ g_code_block_unlock_src(dest);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc de code dont les informations sont à traiter. *
+* *
+* Description : Supprime tous les liens établis avec d'autres blocs de code. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_code_block_delete_all_links(GCodeBlock *block)
{
- G_OBJECT_CLASS(g_instr_block_parent_class)->finalize(G_OBJECT(block));
+ block_link_t *link_src; /* Lien à supprimer #2 */
+ GCodeBlock *other; /* Bloc de l'autre bout */
+ size_t count; /* Quantié de liens présents */
+ size_t i; /* Boucle de parcours */
+ block_link_t *link_dst; /* Lien à supprimer #1 */
+
+ /* Coté sources */
+
+ g_code_block_lock_src(block);
+
+ while (count_flat_array_items(block->from) > 0)
+ {
+ link_src = get_flat_array_item(block->from, 0, sizeof(block_link_t));
+
+ other = link_src->linked;
+
+ g_code_block_lock_dest(other);
+
+ count = count_flat_array_items(other->to);
+
+ for (i = 0; i < count; i++)
+ {
+ link_dst = get_flat_array_item(other->to, i, sizeof(block_link_t));
+
+ if (link_dst->linked == block && link_dst->type == link_src->type)
+ {
+ unref_block_link(link_dst);
+
+ rem_item_from_flat_array(&other->to, i, sizeof(block_link_t));
+
+ break;
+
+ }
+
+ }
+
+ assert(i < count);
+
+ g_code_block_unlock_dest(other);
+
+ unref_block_link(link_src);
+
+ rem_item_from_flat_array(&block->from, 0, sizeof(block_link_t));
+
+ }
+
+ g_code_block_unlock_src(block);
+
+ /* Coté destinations */
+
+ g_code_block_lock_dest(block);
+
+ while (count_flat_array_items(block->to) > 0)
+ {
+ link_dst = get_flat_array_item(block->to, 0, sizeof(block_link_t));
+
+ other = link_dst->linked;
+
+ g_code_block_lock_src(other);
+
+ count = count_flat_array_items(other->from);
+
+ for (i = 0; i < count; i++)
+ {
+ link_src = get_flat_array_item(other->from, i, sizeof(block_link_t));
+
+ if (link_src->linked == block && link_src->type == link_dst->type)
+ {
+ unref_block_link(link_src);
+
+ rem_item_from_flat_array(&other->from, i, sizeof(block_link_t));
+
+ break;
+
+ }
+
+ }
+
+ assert(i < count);
+
+ g_code_block_unlock_src(other);
+
+ unref_block_link(link_dst);
+
+ rem_item_from_flat_array(&block->to, 0, sizeof(block_link_t));
+
+ }
+
+ g_code_block_unlock_dest(block);
}
/******************************************************************************
* *
-* Paramètres : block = bloc de départ des recherches. *
-* addr = ensemble de blocs à parcourir. *
-* final = indique si la cible ou le conteneur est renvoyée. *
+* Paramètres : block = bloc dont les informations sont à consulter. *
* *
-* Description : Recherche le bloc contenant une adresse donnée. *
+* Description : Fournit la quantité de blocs de code pointant vers un autre. *
* *
-* Retour : bloc basique trouvé ou NULL en cas d'échec. *
+* Retour : Nombre de ces origines. *
* *
* Remarques : - *
* *
******************************************************************************/
-GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *block, const vmpa2t *addr, bool final)
+size_t g_code_block_count_sources(const GCodeBlock *block)
{
- return G_INSTR_BLOCK_GET_CLASS(block)->find_by_addr(block, addr, final);
+ size_t result; /* Nombre de liens à renvoyer */
+
+ result = count_flat_array_items(block->from);
+
+ return result;
}
/******************************************************************************
* *
-* Paramètres : block = bloc d'instructions démarrant la visite. *
-* callback = ensemble de blocs à parcourir. *
-* data = donnée utilisateur à associer au parcours. *
+* Paramètres : block = bloc dont les informations sont à consulter. *
+* index = indice de l'élément à retrouver. *
* *
-* Description : Parcourt tous les blocs d'instructions dans un ordre donné. *
+* Description : Fournit les détails d'une origine d'un bloc de code donné. *
* *
-* Retour : true si le parcours a été jusqu'à son terme, false sinon. *
+* Retour : Lien déterminé vers un bloc de code d'origine. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_instr_block_visit(GInstrBlock *block, instr_block_visitor_cb callback, void *data)
+const block_link_t *g_code_block_get_source(GCodeBlock *block, size_t index)
{
- return G_INSTR_BLOCK_GET_CLASS(block)->visit_blocks(block, callback, data);
+ block_link_t *result; /* Détails présents à renvoyer */
+
+ result = get_flat_array_item(block->from, index, sizeof(block_link_t));
+
+ ref_block_link(result);
+
+ return result;
}
/******************************************************************************
* *
-* Paramètres : block = bloc d'instructions à consulter. *
-* list = ensemble de blocs à compléter. [OUT] *
-* count = nombre de blocs au total. [OUT] *
+* Paramètres : block = bloc dont les informations sont à consulter. *
+* *
+* Description : Donne le nombre de blocs de code suivants dans le flot. *
* *
-* Description : Etablit la liste de tous les blocs présents. *
+* Retour : Nombre de ces destinations. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_code_block_count_destinations(const GCodeBlock *block)
+{
+ size_t result; /* Nombre de liens à renvoyer */
+
+ result = count_flat_array_items(block->to);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc dont les informations sont à consulter. *
+* index = indice de l'élément à retrouver. *
+* *
+* Description : Fournit les détails d'une destination de bloc de code. *
+* *
+* Retour : Lien déterminé vers un bloc de code de destination. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const block_link_t *g_code_block_get_destination(GCodeBlock *block, size_t index)
+{
+ block_link_t *result; /* Détails présents à renvoyer */
+
+ result = get_flat_array_item(block->to, index, sizeof(block_link_t));
+
+ ref_block_link(result);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* REGROUPEMENT EN LISTE DE BLOCS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une liste de blocs de code. */
+G_DEFINE_TYPE(GBlockList, g_block_list, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe à initialiser. *
+* *
+* Description : Initialise la classe des listes de blocs de code. *
* *
* Retour : - *
* *
@@ -185,20 +707,23 @@ bool g_instr_block_visit(GInstrBlock *block, instr_block_visitor_cb callback, vo
* *
******************************************************************************/
-void g_instr_block_list_all_blocks(const GInstrBlock *block, GInstrBlock ***list, size_t *count)
+static void g_block_list_class_init(GBlockListClass *class)
{
- G_INSTR_BLOCK_GET_CLASS(block)->list_blocks(block, list, count);
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_block_list_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_block_list_finalize;
}
/******************************************************************************
* *
-* Paramètres : block = bloc d'instructions à consulter. *
-* list = ensemble de blocs à compléter. [OUT] *
-* count = nombre de blocs au total. [OUT] *
+* Paramètres : block = instance à initialiser. *
* *
-* Description : Etablit la liste de tous les blocs terminaux. *
+* Description : Initialise une liste de blocs de code. *
* *
* Retour : - *
* *
@@ -206,19 +731,19 @@ void g_instr_block_list_all_blocks(const GInstrBlock *block, GInstrBlock ***list
* *
******************************************************************************/
-void g_instr_block_list_leafs_blocks(const GInstrBlock *block, GInstrBlock ***list, size_t *count)
+static void g_block_list_init(GBlockList *list)
{
- G_INSTR_BLOCK_GET_CLASS(block)->list_leafs(block, list, count);
+ list->blocks = NULL;
+ list->count = 0;
}
/******************************************************************************
* *
-* Paramètres : block = bloc d'instructions à mettre à jour. *
-* links = bloc contenant les blocs liés au bloc. *
+* Paramètres : block = instance d'objet GLib à traiter. *
* *
-* Description : Définit l'ensemble contenant les blocs liés. *
+* Description : Supprime toutes les références externes. *
* *
* Retour : - *
* *
@@ -226,31 +751,223 @@ void g_instr_block_list_leafs_blocks(const GInstrBlock *block, GInstrBlock ***li
* *
******************************************************************************/
-void g_instr_block_set_links_block(GInstrBlock *block, GInstrBlock *links)
+static void g_block_list_dispose(GBlockList *list)
{
- if (block->links_block != NULL)
- g_object_unref(G_OBJECT(block->links_block));
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < list->count; i++)
+ if (list->blocks[i] != NULL)
+ {
+ g_code_block_delete_all_links(list->blocks[i]);
+ g_object_unref(G_OBJECT(list->blocks[i]));
+ }
- g_object_ref(G_OBJECT(links));
- block->links_block = links;
+ G_OBJECT_CLASS(g_block_list_parent_class)->dispose(G_OBJECT(list));
}
/******************************************************************************
* *
-* Paramètres : block = bloc d'instructions à mettre à jour. *
+* Paramètres : block = instance d'objet GLib à traiter. *
* *
-* Description : Fournit l'ensemble contenant les blocs liés. *
+* Description : Procède à la libération totale de la mémoire. *
* *
-* Retour : Bloc contenant les blocs liés au bloc. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-GInstrBlock *g_instr_block_get_links_block(const GInstrBlock *block)
+static void g_block_list_finalize(GBlockList *list)
{
- return block->links_block;
+ if (list->blocks != NULL)
+ free(list->blocks);
+
+ G_OBJECT_CLASS(g_block_list_parent_class)->finalize(G_OBJECT(list));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : count = quantité finale de blocs présentie. *
+* *
+* Description : Crée une liste de blocs de code. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBlockList *g_block_list_new(size_t count)
+{
+ GBlockList *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_BLOCK_LIST, NULL);
+
+ result->blocks = (GCodeBlock **)calloc(count, sizeof(GCodeBlock *));
+
+ result->count = count;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : list = liste de blocs de code à consulter. *
+* *
+* Description : Compte le nombre de blocs de code représentés. *
+* *
+* Retour : Quantité de blocs de code rassemblés. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_block_list_count_blocks(const GBlockList *list)
+{
+ size_t result; /* Quantité à retourner */
+
+ result = list->count;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : list = liste de blocs de code à compléter. *
+* block = bloc de code à intégrer. *
+* index = indice de la position d'insertion du bloc. *
+* *
+* Description : Ajoute un bloc de code à une liste définie. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_block_list_add_block(GBlockList *list, GCodeBlock *block, size_t index)
+{
+ assert(index < list->count);
+ assert(list->blocks[index] == NULL);
+
+ list->blocks[index] = block;
+
+ g_code_block_set_index(block, index);
+
+}
+
+
+
+/******************************************************************************
+* *
+* Paramètres : list = ensemble des blocs de code à traiter. *
+* *
+* Description : Etablit les liens entre les blocs de code et leurs voisins. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_block_list_resolve_links(const GBlockList *list)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < list->count; i++)
+ g_code_block_resolve_links(list->blocks[i], list);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : list = liste de blocs de code à consulter. *
+* index = indice de la position du bloc recherché. *
+* *
+* Description : Fournit le bloc de code correspondant à un indice de liste. *
+* *
+* Retour : Bloc de code trouvé, ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GCodeBlock *g_block_list_get_block(const GBlockList *list, size_t index)
+{
+ GCodeBlock *result; /* Bloc de code à retourner */
+
+ assert(index < list->count);
+
+ if (index < list->count)
+ result = list->blocks[index];
+ else
+ result = NULL;
+
+ /**
+ * La liste peut être dimensionnée sans avoir été remplie...
+ * Donc on fait attention avec le compteur de références.
+ */
+
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : list = liste de blocs de code à consulter. *
+* addr = localisation à comparer. *
+* *
+* Description : Recherche un bloc de code débutant à une adresse donnée. *
+* *
+* Retour : Bloc de code trouvé ou NULL si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GCodeBlock *g_block_list_find_by_starting_instr(const GBlockList *list, const vmpa2t *addr)
+{
+ GCodeBlock *result; /* Trouvaille à retourner */
+ size_t i; /* Boucle de parcours */
+ GCodeBlock *block; /* Bloc basique analysé */
+
+ result = NULL;
+
+ for (i = 0; i < list->count && result == NULL; i++)
+ {
+ block = list->blocks[i];
+
+ /**
+ * La liste peut être dimensionnée sans avoir été remplie...
+ * Donc on fait attention.
+ */
+
+ assert(block != NULL);
+
+ if (block == NULL)
+ continue;
+
+ if (g_code_block_is_starting_with(block, addr))
+ {
+ result = block;
+ g_object_ref(G_OBJECT(result));
+ }
+
+ }
+
+ return result;
}