summaryrefslogtreecommitdiff
path: root/src/analysis/disass
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-05-28 14:39:56 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-05-28 14:42:41 (GMT)
commit3154db88ce14aa681cc553a8910edba1e69d8c2b (patch)
treec54fa0190da66831c19c83ae57dba117e56387e7 /src/analysis/disass
parented70a0bacfdca738ba29d50e9f1b02290f28b9b8 (diff)
Built the basic blocks list simply at loading.
Diffstat (limited to 'src/analysis/disass')
-rw-r--r--src/analysis/disass/Makefile.am2
-rw-r--r--src/analysis/disass/block.c546
-rw-r--r--src/analysis/disass/block.h111
-rw-r--r--src/analysis/disass/dragon.c44
-rw-r--r--src/analysis/disass/dragon.h4
-rw-r--r--src/analysis/disass/rank.c128
-rw-r--r--src/analysis/disass/routines.c5
7 files changed, 838 insertions, 2 deletions
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);