summaryrefslogtreecommitdiff
path: root/src/analysis/disass/block.c
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/block.c
parented70a0bacfdca738ba29d50e9f1b02290f28b9b8 (diff)
Built the basic blocks list simply at loading.
Diffstat (limited to 'src/analysis/disass/block.c')
-rw-r--r--src/analysis/disass/block.c546
1 files changed, 546 insertions, 0 deletions
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;
+
+}