From 3154db88ce14aa681cc553a8910edba1e69d8c2b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 28 May 2016 16:39:56 +0200
Subject: Built the basic blocks list simply at loading.

---
 ChangeLog                       |  20 ++
 src/analysis/disass/Makefile.am |   2 +-
 src/analysis/disass/block.c     | 546 ++++++++++++++++++++++++++++++++++++++++
 src/analysis/disass/block.h     | 111 ++++++++
 src/analysis/disass/dragon.c    |  44 ++++
 src/analysis/disass/dragon.h    |   4 +
 src/analysis/disass/rank.c      | 128 ++++++++++
 src/analysis/disass/routines.c  |   5 +-
 src/analysis/routine.c          |   6 +-
 src/analysis/routine.h          |   6 +-
 10 files changed, 864 insertions(+), 8 deletions(-)
 create mode 100644 src/analysis/disass/block.c
 create mode 100644 src/analysis/disass/block.h

diff --git a/ChangeLog b/ChangeLog
index 444dbb0..c8bb2c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
 16-05-28  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/analysis/disass/Makefile.am:
+	Add the 'block.[ch]' files to libanalysisdisass_la_SOURCES, and remove
+	the 'macro.[ch]' ones.
+
+	* src/analysis/disass/block.c:
+	* src/analysis/disass/block.h:
+	New entries: build the basic blocks list simply at loading.
+
+	* src/analysis/disass/dragon.c:
+	* src/analysis/disass/dragon.h:
+	Translate dragon nodes into basic blocks.
+
+	* src/analysis/disass/rank.c:
+	* src/analysis/disass/routines.c:
+	* src/analysis/routine.c:
+	* src/analysis/routine.h:
+	Update code.
+
+16-05-28  Cyrille Bagard <nocbos@gmail.com>
+
 	* configure.ac:
 	Remove the Makefile from the 'plugins/python/androperms' directory.
 
diff --git a/src/analysis/disass/Makefile.am b/src/analysis/disass/Makefile.am
index 7223e5a..b6d123c 100644
--- a/src/analysis/disass/Makefile.am
+++ b/src/analysis/disass/Makefile.am
@@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libanalysisdisass.la
 
 libanalysisdisass_la_SOURCES =			\
 	area.h area.c						\
+	block.h block.c						\
 	disassembler.h disassembler.c		\
 	dragon.h dragon.c					\
 	fetch.h fetch.c						\
@@ -10,7 +11,6 @@ libanalysisdisass_la_SOURCES =			\
 	limit.h limit.c						\
 	links.h links.c						\
 	loop.h loop.c						\
-	macro.h macro.c						\
 	output.h output.c					\
 	rank.h rank.c						\
 	routines.h routines.c
diff --git a/src/analysis/disass/block.c b/src/analysis/disass/block.c
new file mode 100644
index 0000000..ff780e6
--- /dev/null
+++ b/src/analysis/disass/block.c
@@ -0,0 +1,546 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * block.c - encadrement des instructions par blocs
+ *
+ * Copyright (C) 2012-2013 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "block.h"
+
+
+#include <assert.h>
+
+
+
+/* ------------------------ MISE EN PLACE DES BLOCS BASIQUES ------------------------ */
+
+
+/* Description d'un bloc basique d'instructions (instance) */
+struct _GBasicBlock
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GArchInstruction *first;                /* Première instruction        */
+    GArchInstruction *last;                 /* Dernière instruction        */
+
+    unsigned int rank;                      /* Rang dans l'exécution       */
+
+};
+
+/* Description d'un bloc basique d'instructions (classe) */
+struct _GBasicBlockClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des blocs d'instructions basique. */
+static void g_basic_block_class_init(GBasicBlockClass *);
+
+/* Initialise un bloc d'instructions basique. */
+static void g_basic_block_init(GBasicBlock *);
+
+/* Supprime toutes les références externes. */
+static void g_basic_block_dispose(GBasicBlock *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_basic_block_finalize(GBasicBlock *);
+
+
+
+/* ------------------------- REGROUPEMENT EN LISTE DE BLOCS ------------------------- */
+
+
+/* Description d'une liste de blocs basiques (instance) */
+struct _GBlockList
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GBasicBlock **blocks;                   /* Blocs basiques rassemblés   */
+    size_t count;                           /* Quantité de ces blocs       */
+
+};
+
+/* Description d'une liste de blocs basiques (classe) */
+struct _GBlockListClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des listes de blocs basiques. */
+static void g_block_list_class_init(GBlockListClass *);
+
+/* Initialise une liste de blocs basiques. */
+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 *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          MISE EN PLACE DES BLOCS BASIQUES                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un bloc d'instructions basique. */
+G_DEFINE_TYPE(GBasicBlock, g_basic_block, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des blocs d'instructions basique.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_basic_block_class_init(GBasicBlockClass *class)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(class);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_basic_block_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_basic_block_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise un bloc d'instructions basique.                   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_basic_block_init(GBasicBlock *block)
+{
+    block->rank = -1;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_basic_block_dispose(GBasicBlock *block)
+{
+    g_object_ref(G_OBJECT(block->first));
+    g_object_ref(G_OBJECT(block->last));
+
+    G_OBJECT_CLASS(g_basic_block_parent_class)->dispose(G_OBJECT(block));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_basic_block_finalize(GBasicBlock *block)
+{
+    G_OBJECT_CLASS(g_basic_block_parent_class)->finalize(G_OBJECT(block));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : first = première instruction du bloc.                        *
+*                last  = dernière instruction du bloc.                        *
+*                                                                             *
+*  Description : Crée un bloc basique d'exécution d'instructions.             *
+*                                                                             *
+*  Retour      : Adresse de la structure mise en place.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBasicBlock *g_basic_block_new(GArchInstruction *first, GArchInstruction *last)
+{
+    GBasicBlock *result;                     /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_BASIC_BLOCK, NULL);
+
+    result->first = first;
+    result->last = last;
+
+    g_object_ref(G_OBJECT(result->first));
+    g_object_ref(G_OBJECT(result->last));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = bloc d'instructions à consulter.                     *
+*                first = instruction de départ du bloc. [OUT]                 *
+*                last  = dernière instruction du bloc. [OUT]                  *
+*                                                                             *
+*  Description : Fournit les instructions limites d'un bloc basique.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_basic_block_get_boundary(const GBasicBlock *block, GArchInstruction **first, GArchInstruction **last)
+{
+    if (first != NULL)
+        *first = block->first;
+
+    if (last != NULL)
+        *last = block->last;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = bloc d'instructions à consulter.                     *
+*                start = adresse de départ du bloc. [OUT]                     *
+*                end   = dernière adresse du bloc. [OUT]                      *
+*                                                                             *
+*  Description : Fournit les adresses limites d'un bloc basique.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_basic_block_get_boundary_addresses(const GBasicBlock *block, vmpa2t *start, vmpa2t *end)
+{
+    const mrange_t *range;                  /* Couverture d'instruction    */
+
+    if (start != NULL)
+    {
+        range = g_arch_instruction_get_range(block->first);
+        copy_vmpa(start, get_mrange_addr(range));
+    }
+
+    if (end != NULL)
+    {
+        range = g_arch_instruction_get_range(block->last);
+        copy_vmpa(end, get_mrange_addr(range));
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = bloc d'instructions à consulter.                     *
+*                                                                             *
+*  Description : Fournit le rang du bloc basique dans le flot d'exécution.    *
+*                                                                             *
+*  Retour      : Indice supérieur ou égal à zéro.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+unsigned int g_basic_block_get_rank(const GBasicBlock *block)
+{
+    return block->rank;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = bloc d'instructions à consulter.                     *
+*                rank  = Indice supérieur à zéro à prendre en compte.         *
+*                                                                             *
+*  Description : Définit le rang du bloc basique dans le flot d'exécution.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_basic_block_set_rank(GBasicBlock *block, unsigned int rank)
+{
+    block->rank = rank;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           REGROUPEMENT EN LISTE DE BLOCS                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une liste de blocs basiques. */
+G_DEFINE_TYPE(GBlockList, g_block_list, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des listes de blocs basiques.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_block_list_class_init(GBlockListClass *class)
+{
+    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 = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une liste de blocs basiques.                      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_block_list_init(GBlockList *list)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_block_list_dispose(GBlockList *list)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < list->count; i++)
+        if (list->blocks[i] != NULL)
+            g_object_unref(G_OBJECT(list->blocks[i]));
+
+    G_OBJECT_CLASS(g_block_list_parent_class)->dispose(G_OBJECT(list));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_block_list_finalize(GBlockList *list)
+{
+    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 basiques.                            *
+*                                                                             *
+*  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_BASIC_BLOCK, NULL);
+
+    result->blocks = (GBasicBlock **)calloc(count, sizeof(GBasicBlock *));
+
+    result->count = count;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = liste de blocs basiques à consulter.                  *
+*                                                                             *
+*  Description : Compte le nombre de blocs basiques représentés.              *
+*                                                                             *
+*  Retour      : Quantité de blocs basiques rassemblés.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_block_list_count_blocks(const GBlockList *list)
+{
+    return list->count;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list  = liste de blocs basiques à compléter.                 *
+*                block = bloc d'instructions basique à intégrer.              *
+*                index = indice de la position d'insertion du bloc.           *
+*                                                                             *
+*  Description : Ajoute un bloc basique à une liste définie.                  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_block_list_add_block(GBlockList *list, GBasicBlock *block, size_t index)
+{
+    assert(index < list->count);
+    assert(list->blocks[index] == NULL);
+
+    list->blocks[index] = block;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list  = liste de blocs basiques à consulter.                 *
+*                index = indice de la position du bloc recherché.             *
+*                                                                             *
+*  Description : Fournit un bloc basique à d'une liste définie.               *
+*                                                                             *
+*  Retour      : Bloc d'instructions basique trouvé.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBasicBlock *g_block_list_get_block(GBlockList *list, size_t index)
+{
+    assert(index < list->count);
+
+    return list->blocks[index];
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list  = liste de blocs basiques à consulter.                 *
+*                instr = instruction de début de bloc recherchée.             *
+*                                                                             *
+*  Description : Recherche un bloc basique selon une première instruction.    *
+*                                                                             *
+*  Retour      : Bloc basique trouvé ou NULL si aucun.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBasicBlock *g_block_list_find_by_starting_instr(const GBlockList *list, GArchInstruction *instr)
+{
+    GBasicBlock *result;                    /* Trouvaille à retourner      */
+    size_t i;                               /* Boucle de parcours          */
+    GBasicBlock *block;                     /* Bloc basique analysé        */
+    GArchInstruction *first;                /* Première instruction du bloc*/
+
+    result = NULL;
+
+    for (i = 0; i < list->count && result == NULL; i++)
+    {
+        block = list->blocks[i];
+
+        g_basic_block_get_boundary(block, &first, NULL);
+
+        if (instr == first)
+            result = block;
+
+    }
+
+    return result;
+
+}
diff --git a/src/analysis/disass/block.h b/src/analysis/disass/block.h
new file mode 100644
index 0000000..8d38976
--- /dev/null
+++ b/src/analysis/disass/block.h
@@ -0,0 +1,111 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * block.h - prototypes pour l'encadrement des instructions par blocs
+ *
+ * Copyright (C) 2012-2013 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_DISASS_BLOCK_H
+#define _ANALYSIS_DISASS_BLOCK_H
+
+
+#include <glib-object.h>
+
+
+#include "../../arch/instruction.h"
+
+
+
+/* ------------------------ MISE EN PLACE DES BLOCS BASIQUES ------------------------ */
+
+
+#define G_TYPE_BASIC_BLOCK              g_basic_block_get_type()
+#define G_BASIC_BLOCK(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), g_basic_block_get_type(), GBasicBlock))
+#define G_IS_BASIC_BLOCK(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_basic_block_get_type()))
+#define G_BASIC_BLOCK_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BASIC_BLOCK, GBasicBlockClass))
+#define G_IS_BASIC_BLOCK_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BASIC_BLOCK))
+#define G_BASIC_BLOCK_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BASIC_BLOCK, GBasicBlockClass))
+
+
+/* Description d'un bloc basique d'instructions (instance) */
+typedef struct _GBasicBlock GBasicBlock;
+
+/* Description d'un bloc basique d'instructions (classe) */
+typedef struct _GBasicBlockClass GBasicBlockClass;
+
+
+/* Indique le type défini pour un bloc d'instructions basique. */
+GType g_basic_block_get_type(void);
+
+/* Crée un bloc basique d'exécution d'instructions. */
+GBasicBlock *g_basic_block_new(GArchInstruction *, GArchInstruction *);
+
+/* Fournit les instructions limites d'un bloc basique. */
+void g_basic_block_get_boundary(const GBasicBlock *, GArchInstruction **, GArchInstruction **);
+
+/* Fournit les adresses limites d'un bloc basique. */
+void g_basic_block_get_boundary_addresses(const GBasicBlock *, vmpa2t *, vmpa2t *);
+
+/* Fournit le rang du bloc basique dans le flot d'exécution. */
+unsigned int g_basic_block_get_rank(const GBasicBlock *);
+
+/* Définit le rang du bloc basique dans le flot d'exécution. */
+void g_basic_block_set_rank(GBasicBlock *, unsigned int);
+
+
+
+/* ------------------------- REGROUPEMENT EN LISTE DE BLOCS ------------------------- */
+
+
+#define G_TYPE_BLOCK_LIST               g_block_list_get_type()
+#define G_BLOCK_LIST(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_block_list_get_type(), GBasicBlock))
+#define G_IS_BLOCK_LIST(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_block_list_get_type()))
+#define G_BLOCK_LIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BLOCK_LIST, GBasicBlockClass))
+#define G_IS_BLOCK_LIST_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BLOCK_LIST))
+#define G_BLOCK_LIST_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BLOCK_LIST, GBasicBlockClass))
+
+
+/* Description d'une liste de blocs basiques (instance) */
+typedef struct _GBlockList GBlockList;
+
+/* Description d'une liste de blocs basiques (classe) */
+typedef struct _GBlockListClass GBlockListClass;
+
+
+/* Indique le type défini pour une liste de blocs basiques. */
+GType g_block_list_get_type(void);
+
+/* Crée une liste de blocs basiques. */
+GBlockList *g_block_list_new(size_t);
+
+/* Compte le nombre de blocs basiques représentés. */
+size_t g_block_list_count_blocks(const GBlockList *);
+
+/* Ajoute un bloc basique à une liste définie. */
+void g_block_list_add_block(GBlockList *, GBasicBlock *, size_t);
+
+/* Fournit un bloc basique à d'une liste définie. */
+GBasicBlock *g_block_list_get_block(GBlockList *, size_t );
+
+/* Recherche un bloc basique selon une première instruction. */
+GBasicBlock *g_block_list_find_by_starting_instr(const GBlockList *, GArchInstruction *);
+
+
+
+#endif  /* _ANALYSIS_DISASS_BLOCK_H */
diff --git a/src/analysis/disass/dragon.c b/src/analysis/disass/dragon.c
index 75b8bb7..98b1cd6 100644
--- a/src/analysis/disass/dragon.c
+++ b/src/analysis/disass/dragon.c
@@ -735,3 +735,47 @@ dragon_node *find_knight_node_for_instruction(const dragon_knight *knight, bool
     return result;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : knight = rassemblement des complexités de code.              *
+*                                                                             *
+*  Description : Traduit une complexité de noeuds en liste de blocs basiques. *
+*                                                                             *
+*  Retour      : Liste de blocs basiques créés.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBlockList *translate_dragon_knight(const dragon_knight *knight)
+{
+    GBlockList *result;                     /* Liste à retourner           */
+    dragon_node *nodes;                     /* Liste des noeuds détectés   */
+    size_t count;                           /* Taille de cette liste       */
+    size_t i;                               /* Boucle de parcours          */
+    dragon_node *node;                      /* Noeud à traiter             */
+    GArchInstruction *first;                /* Première instruction        */
+    GArchInstruction *last;                 /* Dernière instruction        */
+    GBasicBlock *block;                     /* Nouveau bloc basique        */
+
+    get_dragon_knight_content(knight, &nodes, &count);
+
+    result = g_block_list_new(count);
+
+    for (i = 0; i < count; i++)
+    {
+        node = get_dragon_node(nodes, i);
+
+        get_dragon_node_bounding_instructions(node, &first, &last);
+
+        block = g_basic_block_new(first, last);
+
+        g_block_list_add_block(result, block, i);
+
+    }
+
+    return result;
+
+}
diff --git a/src/analysis/disass/dragon.h b/src/analysis/disass/dragon.h
index 3449e6f..9e206f3 100644
--- a/src/analysis/disass/dragon.h
+++ b/src/analysis/disass/dragon.h
@@ -25,6 +25,7 @@
 #define _ANALYSIS_DISASS_DRAGON_H
 
 
+#include "block.h"
 #include "../../arch/processor.h"
 #include "../../common/bits.h"
 
@@ -88,6 +89,9 @@ size_t get_dragon_knight_node_index(const dragon_knight *, dragon_node *);
 /* Recherche un noeud selon son intruction de départ. */
 dragon_node *find_knight_node_for_instruction(const dragon_knight *, bool, const GArchInstruction *);
 
+/* Traduit une complexité de noeuds en liste de blocs basiques. */
+GBlockList *translate_dragon_knight(const dragon_knight *);
+
 
 
 #endif  /* _ANALYSIS_DISASS_DRAGON_H */
diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c
index 85d9e66..3694d04 100644
--- a/src/analysis/disass/rank.c
+++ b/src/analysis/disass/rank.c
@@ -24,6 +24,10 @@
 #include "rank.h"
 
 
+
+
+#if 0
+
 #include <assert.h>
 #include <sys/param.h>
 
@@ -263,3 +267,127 @@ void rank_routine_blocks(GBinRoutine *routine)
 
 
 }
+
+
+
+#endif
+
+
+
+
+
+
+
+#include <assert.h>
+
+
+
+/* Classe les blocs basiques d'une routine. */
+void rank_routine_block(const GBlockList *, GBasicBlock *);
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list  = ensemble de blocs basiques à traiter.                *
+*                block = bloc d'analyse courant.                              *
+*                                                                             *
+*  Description : Classe les blocs basiques d'une routine.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void rank_routine_block(const GBlockList *list, GBasicBlock *block)
+{
+    unsigned int next;                      /* Rang suivant obtenu         */
+    GArchInstruction *last;                 /* Dernière instruction du bloc*/
+    GArchInstruction **dests;               /* Instr. visée par une autre  */
+    InstructionLinkType *types;             /* Type de lien entre lignes   */
+    size_t dcount;                          /* Nombre de liens de dest.    */
+    size_t i;                               /* Boucle de parcours          */
+    GBasicBlock *target;                    /* Bloc ciblé par un lien      */
+    unsigned int rank;                      /* Rang à constituer           */
+
+    next = g_basic_block_get_rank(block) + 1;
+
+    g_basic_block_get_boundary(block, NULL, &last);
+
+    g_arch_instruction_rlock_dest(last);
+    dcount = g_arch_instruction_get_destinations(last, &dests, &types, NULL);
+
+    for (i = 0; i < dcount; i++)
+    {
+        /* La boucle de remontée n'abaisse pas les rangs */
+        if (types[i] == ILT_LOOP) continue;
+
+        target = g_block_list_find_by_starting_instr(list, dests[i]);
+
+        /**
+         * Les sauts ne se font pas toujours à l'intérieur d'une même fonction.
+         * Par exemple sous ARM :
+         *
+         *    00008358 <call_gmon_start>:
+         *        ....
+         *        8362:       f7ff bfcf       b.w     8304 <_init+0x38>
+         *        ....
+         *
+         */
+
+        if (target != NULL)
+        {
+            rank = g_basic_block_get_rank(target);
+
+            if (next > rank)
+            {
+                g_basic_block_set_rank(target, rank);
+
+                rank_routine_block(list, target);
+
+            }
+
+        }
+
+    }
+
+    g_arch_instruction_runlock_dest(last);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : routine = routine regroupant les blocs à traiter.            *
+*                                                                             *
+*  Description : Classe les blocs des routines.                               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void rank_routine_blocks(GBinRoutine *routine)
+{
+    GBlockList *blocks;                     /* Ensemble des blocs d'instr. */
+    GBasicBlock *start;                     /* Bloc basique de départ      */
+
+    blocks = g_binary_routine_get_basic_blocks(routine);
+
+    start = g_block_list_get_block(blocks, 0 /* FIXME */);
+    assert(start != NULL);
+
+
+
+
+    rank_routine_block(blocks, start);
+
+
+
+
+
+
+}
diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c
index de515d0..9f9c3b6 100644
--- a/src/analysis/disass/routines.c
+++ b/src/analysis/disass/routines.c
@@ -292,6 +292,7 @@ void g_routines_study_handle_blocks(GRoutinesStudy *study, size_t index)
     const vmpa2t *start;                    /* Adresse de départ           */
     const instr_coverage *coverage;         /* Instructions couvertes      */
     dragon_knight *knight;                  /* Complexité de code posée    */
+    GBlockList *blocks;                     /* Liste de blocs basiques     */
 
     routine = study->routines[index];
 
@@ -320,7 +321,9 @@ void g_routines_study_handle_blocks(GRoutinesStudy *study, size_t index)
 
     detect_loops_in_code(knight);
 
-    group_routine_instructions(routine, knight);
+    blocks = translate_dragon_knight(knight);
+
+    g_binary_routine_set_basic_blocks(routine, blocks);
 
     rank_routine_blocks(routine);
 
diff --git a/src/analysis/routine.c b/src/analysis/routine.c
index a91e53a..559b9bf 100644
--- a/src/analysis/routine.c
+++ b/src/analysis/routine.c
@@ -56,7 +56,7 @@ struct _GBinRoutine
     size_t locals_count;                    /* Nombre de variables locales */
 
     GArchInstruction *instr;                /* Instructions natives        */
-    GInstrBlock *blocks;                    /* Blocs basiques d'instruct°  */
+    GBlockList *blocks;                     /* Blocs basiques d'instruct°  */
     GDecInstruction *dinstr;                /* Instructions décompilées    */
 
 };
@@ -757,7 +757,7 @@ void g_binary_routine_set_instructions(GBinRoutine *routine, GArchInstruction *i
 *                                                                             *
 ******************************************************************************/
 
-GInstrBlock *g_binary_routine_get_basic_blocks(const GBinRoutine *routine)
+GBlockList *g_binary_routine_get_basic_blocks(const GBinRoutine *routine)
 {
     return routine->blocks;
 
@@ -777,7 +777,7 @@ GInstrBlock *g_binary_routine_get_basic_blocks(const GBinRoutine *routine)
 *                                                                             *
 ******************************************************************************/
 
-void g_binary_routine_set_basic_blocks(GBinRoutine *routine, GInstrBlock *blocks)
+void g_binary_routine_set_basic_blocks(GBinRoutine *routine, GBlockList *blocks)
 {
     if (routine->blocks != NULL)
         g_object_unref(G_OBJECT(routine->blocks));
diff --git a/src/analysis/routine.h b/src/analysis/routine.h
index 177547b..9ee2c2f 100644
--- a/src/analysis/routine.h
+++ b/src/analysis/routine.h
@@ -30,8 +30,8 @@
 #include <sys/types.h>
 
 
-#include "block.h"
 #include "variable.h"
+#include "disass/block.h"
 //#include "../arch/instruction.h"
 #include "../decomp/instruction.h"
 
@@ -164,10 +164,10 @@ GArchInstruction *g_binary_routine_get_instructions(const GBinRoutine *);
 void g_binary_routine_set_instructions(GBinRoutine *, GArchInstruction *);
 
 /* Fournit les blocs basiques de la routine. */
-GInstrBlock *g_binary_routine_get_basic_blocks(const GBinRoutine *);
+GBlockList *g_binary_routine_get_basic_blocks(const GBinRoutine *);
 
 /* Définit les blocs basiques de la routine. */
-void g_binary_routine_set_basic_blocks(GBinRoutine *, GInstrBlock *);
+void g_binary_routine_set_basic_blocks(GBinRoutine *, GBlockList *);
 
 /* Fournit les instructions décompilées correspondantes. */
 GDecInstruction *g_binary_routine_get_decomp_instructions(const GBinRoutine *);
-- 
cgit v0.11.2-87-g4458