summaryrefslogtreecommitdiff
path: root/src/format/preload.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format/preload.c')
-rw-r--r--src/format/preload.c534
1 files changed, 534 insertions, 0 deletions
diff --git a/src/format/preload.c b/src/format/preload.c
new file mode 100644
index 0000000..145dfd9
--- /dev/null
+++ b/src/format/preload.c
@@ -0,0 +1,534 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * preload.c - préchargement d'instructions à partir d'un format
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide 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.
+ *
+ * Chrysalide 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 "preload.h"
+
+
+#include "preload-int.h"
+
+
+
+/* Initialise la classe des préchargements à partir d'un format. */
+static void g_preload_info_class_init(GPreloadInfoClass *);
+
+/* Initialise une instance de préchargement à partir de format. */
+static void g_preload_info_init(GPreloadInfo *);
+
+/* Supprime toutes les références externes. */
+static void g_preload_info_dispose(GPreloadInfo *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_preload_info_finalize(GPreloadInfo *);
+
+
+
+/* Indique le type défini pour un préchargement à partir d'un format. */
+G_DEFINE_TYPE(GPreloadInfo, g_preload_info, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des préchargements à partir d'un format.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_preload_info_class_init(GPreloadInfoClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_preload_info_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_preload_info_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à initialiser. *
+* *
+* Description : Initialise une instance de préchargement à partir de format. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_preload_info_init(GPreloadInfo *info)
+{
+ info->instructions = NULL;
+
+ info->comments = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_preload_info_dispose(GPreloadInfo *info)
+{
+ GArchInstruction *instr; /* Instruction à libérer */
+ GDbComment *comment; /* Commentaire à libérer */
+
+ g_preload_info_lock_instructions(info);
+
+ _g_preload_info_drain_instructions(info);
+
+ g_preload_info_unlock_instructions(info);
+
+ g_preload_info_lock_comments(info);
+
+ while (_g_preload_info_count_comments(info) > 0)
+ {
+ comment = _g_preload_info_get_comment(info, 0);
+
+ rem_item_from_flat_array(&info->comments, 0, sizeof(GDbComment *));
+
+ g_object_unref(G_OBJECT(comment));
+
+ }
+
+ g_preload_info_unlock_comments(info);
+
+ G_OBJECT_CLASS(g_preload_info_parent_class)->dispose(G_OBJECT(info));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_preload_info_finalize(GPreloadInfo *info)
+{
+ G_OBJECT_CLASS(g_preload_info_parent_class)->finalize(G_OBJECT(info));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée une nouvelle collecte d'informations préchargées. *
+* *
+* Retour : Adresse de l'instance mise en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GPreloadInfo *g_preload_info_new(void)
+{
+ GPreloadInfo *result; /* Nouveau preloade à renvoyer */
+
+ result = g_object_new(G_TYPE_PRELOAD_INFO, NULL);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = préchargements à mettre à jour. *
+* *
+* Description : Verrouille les accès à la liste des instructions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_lock_instructions(GPreloadInfo *info)
+{
+ lock_flat_array(&info->instructions);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = préchargements à mettre à jour. *
+* *
+* Description : Déverrouille les accès à la liste des instructions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_unlock_instructions(GPreloadInfo *info)
+{
+ unlock_flat_array(&info->instructions);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à mettre à jour. *
+* instr = instruction à venir associer. *
+* *
+* Description : Ajoute une instruction supplémentaire aux préchargements. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_add_instruction(GPreloadInfo *info, GArchInstruction *instr)
+{
+ int cmp_instr_by_addr(const GArchInstruction **a, const GArchInstruction **b)
+ {
+ const mrange_t *range_a; /* Emplacement pour l'instr. A */
+ const mrange_t *range_b; /* Emplacement pour l'instr. B */
+
+ range_a = g_arch_instruction_get_range(*a);
+ range_b = g_arch_instruction_get_range(*b);
+
+ return cmp_vmpa(get_mrange_addr(range_a), get_mrange_addr(range_b));
+
+ }
+
+ g_preload_info_lock_instructions(info);
+
+ insert_item_into_flat_array(&info->instructions, &instr, sizeof(GArchInstruction *),
+ (__compar_fn_t)cmp_instr_by_addr);
+
+ g_preload_info_unlock_instructions(info);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à consulter. *
+* *
+* Description : Indique la quantité d'instructions préchargées disponibles. *
+* *
+* Retour : Nombre d'instructions attachées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t _g_preload_info_count_instructions(const GPreloadInfo *info)
+{
+ size_t result; /* Décompte à retourner */
+
+ result = count_flat_array_items(info->instructions);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à consulter. *
+* index = indice de l'instruction concernée. *
+* *
+* Description : Fournit une instruction préchargée donnée. *
+* *
+* Retour : Instruction trouvée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *_g_preload_info_get_instruction(const GPreloadInfo *info, size_t index)
+{
+ GArchInstruction *result; /* Opérande à retourner */
+ GArchInstruction **ptr; /* Adresse dans le tableau */
+
+ ptr = get_flat_array_item(info->instructions, index, sizeof(GArchInstruction *));
+
+ result = *ptr;
+
+ g_object_ref(G_OBJECT(result));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à manipuler. *
+* *
+* Description : Dépile une instruction présente dans les préchargements. *
+* *
+* Retour : Instruction retirée ou NULL si aucune. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *g_preload_info_pop_instruction(GPreloadInfo *info)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+ GArchInstruction **ptr; /* Adresse dans le tableau */
+
+ g_preload_info_lock_instructions(info);
+
+ if (_g_preload_info_count_instructions(info) == 0)
+ result = NULL;
+
+ else
+ {
+ ptr = get_flat_array_item(info->instructions, 0, sizeof(GArchInstruction *));
+ result = *ptr;
+
+ rem_item_from_flat_array(&info->instructions, 0, sizeof(GArchInstruction *));
+
+ }
+
+ g_preload_info_unlock_instructions(info);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à manipuler. *
+* *
+* Description : Retire des préchargements toutes les instructions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void _g_preload_info_drain_instructions(GPreloadInfo *info)
+{
+ GArchInstruction *instr; /* Instruction à libérer */
+
+ while (_g_preload_info_count_instructions(info) > 0)
+ {
+ instr = _g_preload_info_get_instruction(info, 0);
+
+ rem_item_from_flat_array(&info->instructions, 0, sizeof(GArchInstruction *));
+
+ g_object_unref(G_OBJECT(instr));
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = préchargements à mettre à jour. *
+* *
+* Description : Verrouille les accès à la liste des commentaires. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_lock_comments(GPreloadInfo *info)
+{
+ lock_flat_array(&info->comments);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = préchargements à mettre à jour. *
+* *
+* Description : Déverrouille les accès à la liste des commentaires. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_unlock_comments(GPreloadInfo *info)
+{
+ unlock_flat_array(&info->comments);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à mettre à jour. *
+* comment = commentaire à venir associer. *
+* *
+* Description : Ajoute un commentaire supplémentaire aux préchargements. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_add_comment(GPreloadInfo *info, GDbComment *comment)
+{
+ int cmp_comment_by_addr(const GDbComment * const *a, const GDbComment * const *b)
+ {
+ const vmpa2t *addr_a; /* Position du commentaire A */
+ const vmpa2t *addr_b; /* Position du commentaire B */
+
+ addr_a = g_db_comment_get_address(*a);
+ addr_b = g_db_comment_get_address(*b);
+
+ return cmp_vmpa(addr_a, addr_b);
+
+ }
+
+ g_preload_info_lock_comments(info);
+
+ insert_item_into_flat_array(&info->comments, &comment, sizeof(GDbComment *),
+ (__compar_fn_t)cmp_comment_by_addr);
+
+ g_preload_info_unlock_comments(info);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à consulter. *
+* *
+* Description : Indique la quantité de commentaires préchargés disponibles. *
+* *
+* Retour : Nombre de commentaires attachés. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t _g_preload_info_count_comments(const GPreloadInfo *info)
+{
+ size_t result; /* Décompte à retourner */
+
+ result = count_flat_array_items(info->comments);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à consulter. *
+* index = indice de l'instruction concernée. *
+* *
+* Description : Fournit un commentaire préchargé donné. *
+* *
+* Retour : Commentaire trouvé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDbComment *_g_preload_info_get_comment(const GPreloadInfo *info, size_t index)
+{
+ GDbComment *result; /* Opérande à retourner */
+ GDbComment **ptr; /* Adresse dans le tableau */
+
+ ptr = get_flat_array_item(info->comments, index, sizeof(GDbComment *));
+
+ result = *ptr;
+
+ g_object_ref(G_OBJECT(result));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à manipuler. *
+* *
+* Description : Dépile un commentaire présent dans les préchargements. *
+* *
+* Retour : Commentaire retiré ou NULL si aucune. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDbComment *g_preload_info_pop_comment(GPreloadInfo *info)
+{
+ GDbComment *result; /* Instruction à retourner */
+ GDbComment **ptr; /* Adresse dans le tableau */
+
+ g_preload_info_lock_comments(info);
+
+ if (_g_preload_info_count_comments(info) == 0)
+ result = NULL;
+
+ else
+ {
+ ptr = get_flat_array_item(info->comments, 0, sizeof(GDbComment *));
+ result = *ptr;
+
+ rem_item_from_flat_array(&info->comments, 0, sizeof(GDbComment *));
+
+ }
+
+ g_preload_info_unlock_comments(info);
+
+ return result;
+
+}