summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analysis/disass/instructions.c14
-rw-r--r--src/analysis/disass/routines.c14
-rw-r--r--src/core/formats.c8
-rw-r--r--src/core/formats.h3
-rwxr-xr-xsrc/format/dex/dex.c3
-rwxr-xr-xsrc/format/dex/dex.h2
-rw-r--r--src/format/dwarf/v2/dwarf.c3
-rw-r--r--src/format/dwarf/v2/dwarf.h2
-rw-r--r--src/format/dwarf/v3/dwarf.c3
-rw-r--r--src/format/dwarf/v3/dwarf.h2
-rw-r--r--src/format/dwarf/v4/dwarf.c3
-rw-r--r--src/format/dwarf/v4/dwarf.h2
-rw-r--r--src/format/elf/Makefile.am1
-rw-r--r--src/format/elf/elf.c5
-rw-r--r--src/format/elf/elf.h2
-rw-r--r--src/format/elf/loading.c291
-rw-r--r--src/format/elf/loading.h71
-rw-r--r--src/format/elf/symbols.c328
-rw-r--r--src/format/elf/symbols.h6
-rw-r--r--src/format/format-int.h2
-rw-r--r--src/format/format.c12
-rw-r--r--src/format/format.h2
-rw-r--r--src/glibext/delayed.c13
-rw-r--r--src/glibext/delayed.h7
-rw-r--r--src/gtkext/gtkstatusstack.c160
-rw-r--r--src/gtkext/gtkstatusstack.h3
-rwxr-xr-xsrc/gui/core/Makefile.am1
-rw-r--r--src/gui/core/global.c68
-rw-r--r--src/gui/core/global.h40
-rw-r--r--src/gui/status.c3
-rw-r--r--src/main.c3
31 files changed, 849 insertions, 228 deletions
diff --git a/src/analysis/disass/instructions.c b/src/analysis/disass/instructions.c
index 7e76a5d..b88d69f 100644
--- a/src/analysis/disass/instructions.c
+++ b/src/analysis/disass/instructions.c
@@ -112,7 +112,7 @@ static void g_instructions_study_class_init(GInstructionsStudyClass *klass)
/******************************************************************************
* *
-* Paramètres : computing = instance à initialiser. *
+* Paramètres : study = instance à initialiser. *
* *
* Description : Initialise une tâche d'étude d'instructions. *
* *
@@ -130,7 +130,7 @@ static void g_instructions_study_init(GInstructionsStudy *study)
/******************************************************************************
* *
-* Paramètres : computing = instance d'objet GLib à traiter. *
+* Paramètres : study = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -140,16 +140,16 @@ static void g_instructions_study_init(GInstructionsStudy *study)
* *
******************************************************************************/
-static void g_instructions_study_dispose(GInstructionsStudy *computing)
+static void g_instructions_study_dispose(GInstructionsStudy *study)
{
- G_OBJECT_CLASS(g_instructions_study_parent_class)->dispose(G_OBJECT(computing));
+ G_OBJECT_CLASS(g_instructions_study_parent_class)->dispose(G_OBJECT(study));
}
/******************************************************************************
* *
-* Paramètres : computing = instance d'objet GLib à traiter. *
+* Paramètres : study = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -159,9 +159,9 @@ static void g_instructions_study_dispose(GInstructionsStudy *computing)
* *
******************************************************************************/
-static void g_instructions_study_finalize(GInstructionsStudy *computing)
+static void g_instructions_study_finalize(GInstructionsStudy *study)
{
- G_OBJECT_CLASS(g_instructions_study_parent_class)->finalize(G_OBJECT(computing));
+ G_OBJECT_CLASS(g_instructions_study_parent_class)->finalize(G_OBJECT(study));
}
diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c
index 94afbe4..de515d0 100644
--- a/src/analysis/disass/routines.c
+++ b/src/analysis/disass/routines.c
@@ -117,7 +117,7 @@ static void g_routines_study_class_init(GRoutinesStudyClass *klass)
/******************************************************************************
* *
-* Paramètres : computing = instance à initialiser. *
+* Paramètres : study = instance à initialiser. *
* *
* Description : Initialise une tâche d'étude de routines. *
* *
@@ -135,7 +135,7 @@ static void g_routines_study_init(GRoutinesStudy *study)
/******************************************************************************
* *
-* Paramètres : computing = instance d'objet GLib à traiter. *
+* Paramètres : study = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -145,16 +145,16 @@ static void g_routines_study_init(GRoutinesStudy *study)
* *
******************************************************************************/
-static void g_routines_study_dispose(GRoutinesStudy *computing)
+static void g_routines_study_dispose(GRoutinesStudy *study)
{
- G_OBJECT_CLASS(g_routines_study_parent_class)->dispose(G_OBJECT(computing));
+ G_OBJECT_CLASS(g_routines_study_parent_class)->dispose(G_OBJECT(study));
}
/******************************************************************************
* *
-* Paramètres : computing = instance d'objet GLib à traiter. *
+* Paramètres : study = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -164,9 +164,9 @@ static void g_routines_study_dispose(GRoutinesStudy *computing)
* *
******************************************************************************/
-static void g_routines_study_finalize(GRoutinesStudy *computing)
+static void g_routines_study_finalize(GRoutinesStudy *study)
{
- G_OBJECT_CLASS(g_routines_study_parent_class)->finalize(G_OBJECT(computing));
+ G_OBJECT_CLASS(g_routines_study_parent_class)->finalize(G_OBJECT(study));
}
diff --git a/src/core/formats.c b/src/core/formats.c
index 5543331..c6b664c 100644
--- a/src/core/formats.c
+++ b/src/core/formats.c
@@ -368,6 +368,7 @@ FormatMatchStatus find_matching_format(GBinContent *content, GExeFormat *parent,
* *
* Paramètres : key = nom technique du processeur recherché. *
* content = contenu binaire pré-chargé à traiter. *
+* parent = contenu binaire principal éventuel déjà chargé. *
* *
* Description : Charge le format binaire correspondant à un type. *
* *
@@ -389,7 +390,12 @@ GBinFormat *load_new_named_format(const char *key, GBinContent *content, GExeFor
if (def == NULL)
result = NULL;
else
- result = def->func(content, parent);
+ {
+ extern GtkStatusStack *get_global_status(void);
+
+ result = def->func(content, parent, get_global_status());
+
+ }
g_rw_lock_reader_unlock(&_formats_lock);
diff --git a/src/core/formats.h b/src/core/formats.h
index 76b57d0..e3dc871 100644
--- a/src/core/formats.h
+++ b/src/core/formats.h
@@ -31,6 +31,7 @@
#include "../format/format.h"
#include "../format/executable.h"
+#include "../gtkext/gtkstatusstack.h"
@@ -50,7 +51,7 @@ typedef enum _FormatMatchStatus
typedef FormatMatchStatus (* format_match_fc) (GBinContent *, GExeFormat *, void *, char **);
/* Méthode de chargement d'un format */
-typedef GBinFormat * (* format_load_fc) (GBinContent *, GExeFormat *);
+typedef GBinFormat * (* format_load_fc) (GBinContent *, GExeFormat *, GtkStatusStack *);
/* Enregistre un détection de format(s) binaire(s). */
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index 2897ee3..3388861 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -233,6 +233,7 @@ static void g_dex_format_finalize(GDexFormat *format)
* *
* Paramètres : content = contenu binaire à parcourir. *
* parent = éventuel format exécutable déjà chargé. *
+ status = barre de statut à tenir informée. *
* *
* Description : Prend en charge un nouveau format Dex. *
* *
@@ -242,7 +243,7 @@ static void g_dex_format_finalize(GDexFormat *format)
* *
******************************************************************************/
-GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent)
+GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent, GtkStatusStack *status)
{
GDexFormat *result; /* Structure à retourner */
GBinFormat *base; /* Version basique du format */
diff --git a/src/format/dex/dex.h b/src/format/dex/dex.h
index 28d2a49..0283a0c 100755
--- a/src/format/dex/dex.h
+++ b/src/format/dex/dex.h
@@ -56,7 +56,7 @@ FormatMatchStatus dex_is_matching(GBinContent *, GExeFormat *, void *, char **);
GType g_dex_format_get_type(void);
/* Prend en charge un nouveau format DEX. */
-GBinFormat *g_dex_format_new(GBinContent *, GExeFormat *);
+GBinFormat *g_dex_format_new(GBinContent *, GExeFormat *, GtkStatusStack *);
/* Présente l'en-tête DEX du format chargé. */
const dex_header *g_dex_format_get_header(const GDexFormat *);
diff --git a/src/format/dwarf/v2/dwarf.c b/src/format/dwarf/v2/dwarf.c
index ccef01f..5e417c3 100644
--- a/src/format/dwarf/v2/dwarf.c
+++ b/src/format/dwarf/v2/dwarf.c
@@ -153,6 +153,7 @@ static void g_dwarfv2_format_finalize(GDwarfV2Format *format)
* *
* Paramètres : content = contenu binaire à parcourir. *
* parent = éventuel format exécutable déjà chargé. *
+ status = barre de statut à tenir informée. *
* *
* Description : Prend en charge un nouveau format DWARF (v2). *
* *
@@ -162,7 +163,7 @@ static void g_dwarfv2_format_finalize(GDwarfV2Format *format)
* *
******************************************************************************/
-GBinFormat *g_dwarfv2_format_new(GBinContent *content, GExeFormat *parent)
+GBinFormat *g_dwarfv2_format_new(GBinContent *content, GExeFormat *parent, GtkStatusStack *status)
{
GDwarfV2Format *result; /* Structure à retourner */
diff --git a/src/format/dwarf/v2/dwarf.h b/src/format/dwarf/v2/dwarf.h
index 360a2e6..732007b 100644
--- a/src/format/dwarf/v2/dwarf.h
+++ b/src/format/dwarf/v2/dwarf.h
@@ -52,7 +52,7 @@ typedef struct _GDwarfV2FormatClass GDwarfV2FormatClass;
GType g_dwarfv2_format_get_type(void);
/* Prend en charge un nouveau format DWARF (v2). */
-GBinFormat *g_dwarfv2_format_new(GBinContent *, GExeFormat *);
+GBinFormat *g_dwarfv2_format_new(GBinContent *, GExeFormat *, GtkStatusStack *);
diff --git a/src/format/dwarf/v3/dwarf.c b/src/format/dwarf/v3/dwarf.c
index d6198f7..0fcd38f 100644
--- a/src/format/dwarf/v3/dwarf.c
+++ b/src/format/dwarf/v3/dwarf.c
@@ -145,6 +145,7 @@ static void g_dwarfv3_format_finalize(GDwarfV3Format *format)
* *
* Paramètres : content = contenu binaire à parcourir. *
* parent = éventuel format exécutable déjà chargé. *
+ status = barre de statut à tenir informée. *
* *
* Description : Prend en charge un nouveau format DWARF (v3). *
* *
@@ -154,7 +155,7 @@ static void g_dwarfv3_format_finalize(GDwarfV3Format *format)
* *
******************************************************************************/
-GBinFormat *g_dwarfv3_format_new(GBinContent *content, GExeFormat *parent)
+GBinFormat *g_dwarfv3_format_new(GBinContent *content, GExeFormat *parent, GtkStatusStack *status)
{
GDwarfV3Format *result; /* Structure à retourner */
diff --git a/src/format/dwarf/v3/dwarf.h b/src/format/dwarf/v3/dwarf.h
index 2aaf891..e316a52 100644
--- a/src/format/dwarf/v3/dwarf.h
+++ b/src/format/dwarf/v3/dwarf.h
@@ -52,7 +52,7 @@ typedef struct _GDwarfV3FormatClass GDwarfV3FormatClass;
GType g_dwarfv3_format_get_type(void);
/* Prend en charge un nouveau format DWARF (v3). */
-GBinFormat *g_dwarfv3_format_new(GBinContent *, GExeFormat *);
+GBinFormat *g_dwarfv3_format_new(GBinContent *, GExeFormat *, GtkStatusStack *);
diff --git a/src/format/dwarf/v4/dwarf.c b/src/format/dwarf/v4/dwarf.c
index 52345e8..995d4f7 100644
--- a/src/format/dwarf/v4/dwarf.c
+++ b/src/format/dwarf/v4/dwarf.c
@@ -153,6 +153,7 @@ static void g_dwarfv4_format_finalize(GDwarfV4Format *format)
* *
* Paramètres : content = contenu binaire à parcourir. *
* parent = éventuel format exécutable déjà chargé. *
+ status = barre de statut à tenir informée. *
* *
* Description : Prend en charge un nouveau format DWARF (v4). *
* *
@@ -162,7 +163,7 @@ static void g_dwarfv4_format_finalize(GDwarfV4Format *format)
* *
******************************************************************************/
-GBinFormat *g_dwarfv4_format_new(GBinContent *content, GExeFormat *parent)
+GBinFormat *g_dwarfv4_format_new(GBinContent *content, GExeFormat *parent, GtkStatusStack *status)
{
GDwarfV4Format *result; /* Structure à retourner */
diff --git a/src/format/dwarf/v4/dwarf.h b/src/format/dwarf/v4/dwarf.h
index af3c2c4..d0f5b7a 100644
--- a/src/format/dwarf/v4/dwarf.h
+++ b/src/format/dwarf/v4/dwarf.h
@@ -52,7 +52,7 @@ typedef struct _GDwarfV4FormatClass GDwarfV4FormatClass;
GType g_dwarfv4_format_get_type(void);
/* Prend en charge un nouveau format DWARF (v4). */
-GBinFormat *g_dwarfv4_format_new(GBinContent *, GExeFormat *);
+GBinFormat *g_dwarfv4_format_new(GBinContent *, GExeFormat *, GtkStatusStack *);
diff --git a/src/format/elf/Makefile.am b/src/format/elf/Makefile.am
index 4317e1d..78dabcd 100644
--- a/src/format/elf/Makefile.am
+++ b/src/format/elf/Makefile.am
@@ -8,6 +8,7 @@ libformatelf_la_SOURCES = \
dynamic.h dynamic.c \
helper_arm.h helper_arm.c \
helper_x86.h helper_x86.c \
+ loading.h loading.c \
program.h program.c \
section.h section.c \
strings.h strings.c \
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index 0c7760c..d09b845 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -230,6 +230,7 @@ static void g_elf_format_finalize(GElfFormat *format)
* *
* Paramètres : content = contenu binaire à parcourir. *
* parent = éventuel format exécutable déjà chargé. *
+ status = barre de statut à tenir informée. *
* *
* Description : Prend en charge un nouveau format ELF. *
* *
@@ -239,7 +240,7 @@ static void g_elf_format_finalize(GElfFormat *format)
* *
******************************************************************************/
-GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent)
+GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatusStack *status)
{
GElfFormat *result; /* Structure à retourner */
@@ -287,7 +288,7 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent)
- if (!load_elf_symbols(result))
+ if (!load_elf_symbols(result, status))
{
/* TODO */
return NULL;
diff --git a/src/format/elf/elf.h b/src/format/elf/elf.h
index d6f631e..3343927 100644
--- a/src/format/elf/elf.h
+++ b/src/format/elf/elf.h
@@ -56,7 +56,7 @@ FormatMatchStatus elf_is_matching(GBinContent *, GExeFormat *, void *, char **);
GType g_elf_format_get_type(void);
/* Prend en charge un nouveau format ELF. */
-GBinFormat *g_elf_format_new(GBinContent *, GExeFormat *);
+GBinFormat *g_elf_format_new(GBinContent *, GExeFormat *, GtkStatusStack *);
/* Présente l'en-tête ELF du format chargé. */
const elf_header *g_elf_format_get_header(const GElfFormat *);
diff --git a/src/format/elf/loading.c b/src/format/elf/loading.c
new file mode 100644
index 0000000..b833720
--- /dev/null
+++ b/src/format/elf/loading.c
@@ -0,0 +1,291 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loading.c - chargements parallèles des symboles de format ELF
+ *
+ * Copyright (C) 2016 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 "loading.h"
+
+
+#include <i18n.h>
+
+
+#include "elf-int.h"
+#include "section.h"
+#include "../../glibext/delayed-int.h"
+#include "../../gui/panels/log.h"
+
+
+
+/* Fraction de routines à limiter (instance) */
+struct _GElfLoading
+{
+ GDelayedWork parent; /* A laisser en premier */
+
+ GElfFormat *format; /* Format à faire évoluer */
+
+ union
+ {
+ struct
+ {
+ const elf_shdr *section; /* Section à éplucher */
+ bool use_virt; /* Représentatio par défaut */
+
+ elf_shdr strtab; /* Section .strtab trouvée */
+ bool has_strtab; /* Présence de cette section */
+
+ };
+
+ };
+
+ elf_loading_cb callback; /* Routine de traitement finale*/
+ phys_t first; /* Position du premier élément */
+ phys_t begin; /* Point de départ du parcours */
+ phys_t end; /* Point d'arrivée exclu */
+
+ activity_id_t id; /* Identifiant pour messages */
+
+};
+
+/* Fraction de routines à limiter (classe) */
+struct _GElfLoadingClass
+{
+ GDelayedWorkClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des tâches des chargements pour ELF. */
+static void g_elf_loading_class_init(GElfLoadingClass *);
+
+/* Initialise une tâche de chargements pour ELF. */
+static void g_elf_loading_init(GElfLoading *);
+
+/* Supprime toutes les références externes. */
+static void g_elf_loading_dispose(GElfLoading *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_elf_loading_finalize(GElfLoading *);
+
+/* Assure le chargement pour un format ELF en différé. */
+static void g_elf_loading_process(GElfLoading *, GtkStatusStack *);
+
+
+
+/* Indique le type défini pour les tâches de chargements pour format ELF. */
+G_DEFINE_TYPE(GElfLoading, g_elf_loading, G_TYPE_DELAYED_WORK);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des tâches des chargements pour ELF. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_loading_class_init(GElfLoadingClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GDelayedWorkClass *work; /* Version en classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_elf_loading_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_elf_loading_finalize;
+
+ work = G_DELAYED_WORK_CLASS(klass);
+
+ work->run = (run_task_fc)g_elf_loading_process;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : loading = instance à initialiser. *
+* *
+* Description : Initialise une tâche de chargements pour ELF. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_loading_init(GElfLoading *loading)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : loading = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_loading_dispose(GElfLoading *loading)
+{
+ G_OBJECT_CLASS(g_elf_loading_parent_class)->dispose(G_OBJECT(loading));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : loading = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_loading_finalize(GElfLoading *loading)
+{
+ G_OBJECT_CLASS(g_elf_loading_parent_class)->finalize(G_OBJECT(loading));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = = ensemble d'instructions désassemblées. *
+* section = prototypes existants à insérer. *
+* use_virt = quantité de ces prototypes. *
+* first = position du premier élément. *
+* begin = point de départ du parcours de liste. *
+* end = point d'arrivée exclu du parcours. *
+* id = identifiant du message affiché à l'utilisateur. *
+* callback = routine de traitements particuliers. *
+* *
+* Description : Crée une tâche de chargement pour ELF différée. *
+* *
+* Retour : Tâche créée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GElfLoading *g_elf_loading_new(GElfFormat *format, const elf_shdr *section, bool use_virt, phys_t first, phys_t begin, phys_t end, activity_id_t id, elf_loading_cb callback)
+{
+ GElfLoading *result; /* Tâche à retourner */
+
+ result = g_object_new(G_TYPE_ELF_LOADING, NULL);
+
+ result->format = format;
+
+ result->section = section;
+ result->use_virt = use_virt;
+
+ result->has_strtab = find_elf_section_by_index(format,
+ ELF_SHDR(format, *section, sh_link),
+ &result->strtab);
+
+ result->callback = callback;
+ result->first = first;
+ result->begin = begin;
+ result->end = end;
+
+ result->id = id;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : study = étude de routines à mener. *
+* status = barre de statut à tenir informée. *
+* *
+* Description : Assure le chargement pour un format ELF en différé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_loading_process(GElfLoading *loading, GtkStatusStack *status)
+{
+ phys_t iter; /* Boucle de parcours */
+ phys_t old; /* Sauvegarde du point d'avant */
+ bool ret; /* Bilan d'un appel */
+
+ for (iter = loading->begin; iter < loading->end; )
+ {
+ old = iter;
+ ret = loading->callback(loading, loading->format, &iter);
+
+ if (!ret)
+ {
+ log_variadic_message(LMT_ERROR, _("Error while loading ELF data @ 0x%08x!"), old);
+ break;
+ }
+
+ gtk_status_stack_update_activity_value(status, loading->id, 1);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : loading = chargement pour ELF à mener. *
+* section = prototypes existants à insérer. [OUT] *
+* use_virt = quantité de ces prototypes. [OUT] *
+* strtab = informations quant à la table des chaînes. [OUT]*
+* has_strtab = validité du champ précédemment renseigné. [OUT] *
+* first = position du premier élément. [OUT] *
+* *
+* Description : Fournit les infos utiles au chargement de symbols internes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_elf_loading_get_internal_info(GElfLoading *loading, const elf_shdr **section, bool *use_virt, const elf_shdr **strtab, bool *has_strtab, phys_t *first)
+{
+ *section = loading->section;
+ *use_virt = loading->use_virt;
+
+ *strtab = &loading->strtab;
+ *has_strtab = loading->has_strtab;
+
+ *first = loading->first;
+
+}
diff --git a/src/format/elf/loading.h b/src/format/elf/loading.h
new file mode 100644
index 0000000..ac7701f
--- /dev/null
+++ b/src/format/elf/loading.h
@@ -0,0 +1,71 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loading.h - prototypes pour les chargements parallèles des symboles de format ELF
+ *
+ * Copyright (C) 2016 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 _FORMAT_ELF_LOADING_H
+#define _FORMAT_ELF_LOADING_H
+
+
+#include "elf.h"
+#include "../../gtkext/gtkstatusstack.h"
+
+
+
+
+//#include "../routine.h"
+//#include "../../arch/processor.h"
+//#include "../../format/executable.h"
+//#include "../../gtkext/gtkstatusstack.h"
+
+
+
+#define G_TYPE_ELF_LOADING g_elf_loading_get_type()
+#define G_ELF_LOADING(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_elf_loading_get_type(), GElfLoading))
+#define G_IS_ELF_LOADING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_elf_loading_get_type()))
+#define G_ELF_LOADING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ELF_LOADING, GElfLoadingClass))
+#define G_IS_ELF_LOADING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ELF_LOADING))
+#define G_ELF_LOADING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ELF_LOADING, GElfLoadingClass))
+
+
+/* Fraction de loading à limiter (instance) */
+typedef struct _GElfLoading GElfLoading;
+
+/* Fraction de loading à limiter (classe) */
+typedef struct _GElfLoadingClass GElfLoadingClass;
+
+
+/* Assure un chargement pour ELF en différé. */
+typedef bool (* elf_loading_cb) (GElfLoading *, GElfFormat *, phys_t *);
+
+
+/* Indique le type défini pour les tâches de chargements pour format ELF. */
+GType g_elf_loading_get_type(void);
+
+/* Crée une tâche de chargement pour ELF différée. */
+GElfLoading *g_elf_loading_new(GElfFormat *, const elf_shdr *, bool, phys_t, phys_t, phys_t, activity_id_t, elf_loading_cb);
+
+/* Fournit les infos utiles au chargement de symbols internes. */
+void g_elf_loading_get_internal_info(GElfLoading *, const elf_shdr **, bool *, const elf_shdr **, bool *, phys_t *);
+
+
+
+#endif /* _FORMAT_ELF_LOADING_H */
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index 29a8c3c..cfd0a09 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -36,6 +36,7 @@
#include "elf-int.h"
#include "helper_arm.h"
#include "helper_x86.h"
+#include "loading.h"
#include "program.h"
#include "section.h"
#include "../mangling/demangler.h"
@@ -47,6 +48,12 @@
+
+
+
+
+
+
/* Enregistre un point d'entrée au sein d'un binaire ELF. */
static void register_elf_entry_point(GElfFormat *, virt_t, phys_t, GBinRoutine *);
@@ -64,8 +71,11 @@ static bool load_all_elf_basic_entry_points(GElfFormat *);
/* -------------------------- DETAIL DES SYMBOLES INTERNES -------------------------- */
+/* Assure le chargement des symboles internes ELF en différé. */
+static bool do_elf_internal_symbol_loading(GElfLoading *, GElfFormat *, phys_t *);
+
/* Charge tous les symboles internes possibles. */
-static bool load_elf_internal_symbols(GElfFormat *);
+static bool load_elf_internal_symbols(GElfFormat *, wgroup_id_t, GtkStatusStack *);
@@ -87,9 +97,13 @@ static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *);
+
+
+
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+ status = barre de statut à tenir informée. *
* *
* Description : Charge en mémoire la liste humaine des symboles. *
* *
@@ -99,18 +113,21 @@ static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *);
* *
******************************************************************************/
-bool load_elf_symbols(GElfFormat *format)
+bool load_elf_symbols(GElfFormat *format, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
+ wgroup_id_t gid; /* Identifiant pour les tâches */
elf_shdr *sections; /* Groupe de sections trouvées */
size_t count; /* Quantité de données */
result = true;
+ gid = g_work_queue_define_work_group(get_work_queue());
+
/* Symboles internes */
- result &= load_elf_internal_symbols(format);
+ result &= load_elf_internal_symbols(format, gid, status);
@@ -150,6 +167,9 @@ bool load_elf_symbols(GElfFormat *format)
}
+
+
+
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
@@ -493,200 +513,262 @@ const char *get_elf_symbol_name(GElfFormat *format, const elf_shdr *sym, const e
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à compléter. *
+* Paramètres : loading = chargement de symboles internes en cours. *
+* format = format ELF à compléter. *
+* iter = tête de lecture évoluant avec le temps. [OUT] *
* *
-* Description : Charge tous les symboles internes possibles. *
+* Description : Assure le chargement des symboles internes ELF en différé. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool load_elf_internal_symbols(GElfFormat *format)
+static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *format, phys_t *iter)
{
bool result; /* Bilan à retourner */
- bool no_name; /* Choix de construction de nom*/
- elf_shdr *sections; /* Groupe de sections trouvées */
- size_t count; /* Quantité de données */
- size_t i; /* Boucle de parcours */
+ elf_sym sym; /* Symbole aux infos visées */
+ virt_t virt; /* Adresse virtuelle */
+ const elf_shdr *section; /* Groupe de sections trouvées */
+ bool use_virt; /* Choix de construction de nom*/
+ const elf_shdr *strtab; /* Section .strtab trouvée */
+ bool has_strtab; /* Présence de cette section */
+ phys_t first; /* Position du premier élément */
+ const char *name; /* Nom du symbole trouvé */
+ GBinFormat *base; /* Version basique du format */
+ vmpa2t addr; /* Localisation d'une routine */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
+ char alt_name[6 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/
+ virt_t final_virt; /* Adresse virtuelle retenue */
+ mrange_t range; /* Couverture mémoire associée */
+ GBinRoutine *routine; /* Nouvelle routine trouvée */
- result = true;
+ result = read_elf_symbol(format, iter, &sym);
+ if (!result) goto geslp_done;
- /* Charge tous les symboles définis dans une section */
- bool add_all_symbols_from_section(GElfFormat *format, const elf_shdr *section, bool use_virt)
- {
- GBinFormat *base; /* Version basique du format */
- elf_shdr strtab; /* Section .strtab trouvée */
- bool has_strtab; /* Présence de cette section */
- phys_t start; /* Début de la zone à traiter */
- phys_t size; /* Taille de cette même zone */
- phys_t iter; /* Boucle de parcours */
- elf_sym sym; /* Symbole aux infos visées */
- virt_t virt; /* Adresse virtuelle */
- virt_t final_virt; /* Adresse virtuelle retenue */
- vmpa2t addr; /* Localisation d'une routine */
- mrange_t range; /* Couverture mémoire associée */
- const char *name; /* Nom du symbole trouvé */
- char alt_name[6 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/
- GBinRoutine *routine; /* Nouvelle routine trouvée */
- GBinSymbol *symbol; /* Nouveau symbole construit */
+ /* On rejette les symboles qui ne sont pas définis au sein du binaire */
- base = G_BIN_FORMAT(format);
+ if (ELF_SYM(format, sym, st_shndx) == 0) goto geslp_done;
- has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, *section, sh_link), &strtab);
+ /* Résolution précise d'adresse */
- get_elf_section_content(format, section, &start, &size, NULL);
+ virt = ELF_SYM(format, sym, st_value);
+ if (virt == 0) goto geslp_done;
- for (iter = start; iter < (start + size); )
- {
- result = read_elf_symbol(format, &iter, &sym);
- if (!result) break;
- /* On rejette les symboles qui ne sont pas définis au sein du binaire */
- if (ELF_SYM(format, sym, st_shndx) == 0) continue;
+ /* TODO */
-#if 0
+ //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value));
- Elf64_Word st_name; /* Symbol name (string tbl index) */
- unsigned char st_info; /* Symbol type and binding */
- unsigned char st_other; /* Symbol visibility */
- Elf64_Section st_shndx; /* Section index */
- Elf64_Addr st_value; /* Symbol value */
- Elf64_Xword st_size; /* Symbol size */
-#endif
+ //init_mrange(&range, &addr, 0);
- if (ELF_SYM(format, sym, st_value) == 0) continue;
+ /* Première ébauche de nom */
- /* Résolution précise d'adresse */
+ g_elf_loading_get_internal_info(loading, &section, &use_virt, &strtab, &has_strtab, &first);
+ if (!has_strtab)
+ name = NULL;
- /* TODO */
+ else
+ name = get_elf_symbol_name(format, section, strtab,
+ ((*iter - first) / ELF_SIZEOF_SYM(format)) - 1);
- //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value));
+ /* Traitements particuliers */
- virt = ELF_SYM(format, sym, st_value);
+ base = G_BIN_FORMAT(format);
- //init_mrange(&range, &addr, 0);
+ switch (ELF_ST_TYPE(format, sym))
+ {
+ case STT_OBJECT:
+ /* Ajustement de la position */
- /* Première ébauche de nom */
+ if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr))
+ {
+ symbol = NULL;
+ break;
+ }
- if (!has_strtab) name = NULL;
- else name = get_elf_symbol_name(format, section, &strtab,
- ((iter - start) / ELF_SIZEOF_SYM(format)) - 1);
+ /* Création d'un nom unique ? */
- /* Traitements particuliers */
+ if (name == NULL)
+ {
+ strcpy(alt_name, "obj_");
- switch (ELF_ST_TYPE(format, sym))
+ if (use_virt)
+ vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL);
+ else
+ vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL);
+
+ name = alt_name;
+
+ }
+
+
+ /* TODO */
+
+ symbol = NULL;
+
+
+ break;
+
+ case STT_FUNC:
+
+ /* Ajustement de la position */
+
+ if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
+ final_virt = virt & ~0x1;
+ else
+ final_virt = virt;
+
+ if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr))
{
- case STT_OBJECT:
+ symbol = NULL;
+ break;
+ }
- /* Ajustement de la position */
+ init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
- if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr))
- {
- symbol = NULL;
- break;
- }
+ /* Création d'un nom unique ? */
- /* Création d'un nom unique ? */
+ if (name == NULL)
+ {
+ strcpy(alt_name, "func_");
- if (name != NULL)
- {
- strcpy(alt_name, "obj_");
+ if (use_virt)
+ vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL);
+ else
+ vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL);
- if (use_virt)
- vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL);
- else
- vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL);
+ name = alt_name;
- }
+ }
+ /* Routine */
- /* TODO */
+ routine = try_to_demangle_routine(name);
- symbol = NULL;
+ g_binary_routine_set_range(routine, &range);
+ /* Symbole uniquement */
- break;
+ symbol = g_binary_symbol_new(STP_ROUTINE);
+ g_binary_symbol_attach_routine(symbol, routine);
- case STT_FUNC:
+ /* Comptabilisation pour le désassemblage brut */
- /* Ajustement de la position */
+ g_binary_format_register_code_point(G_BIN_FORMAT(format), virt, false);
- if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
- final_virt = virt & ~0x1;
- else
- final_virt = virt;
+ break;
- if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr))
- {
- symbol = NULL;
- break;
- }
+ default:
+ symbol = NULL;
+ break;
- init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
+ }
- /* Création d'un nom unique ? */
+ if (symbol != NULL)
+ g_binary_format_add_symbol(base, symbol);
- if (name != NULL)
- {
- strcpy(alt_name, "func_");
+ geslp_done:
- if (use_virt)
- vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL);
- else
- vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL);
+ return result;
- }
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* gid = groupe de travail impliqué. *
+ status = barre de statut à tenir informée. *
+* *
+* Description : Charge tous les symboles internes possibles. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- /* Routine */
+static bool load_elf_internal_symbols(GElfFormat *format, wgroup_id_t gid, GtkStatusStack *status)
+{
+ bool result; /* Bilan à retourner */
+ bool no_name; /* Choix de construction de nom*/
+ activity_id_t msg; /* Message de progression */
+ GWorkQueue *queue; /* Gestionnaire de différés */
+ elf_shdr *dynsym_sections; /* Groupe de sections trouvées */
+ size_t count; /* Quantité de données */
+ elf_shdr *symtab_sections; /* Groupe de sections trouvées */
+ size_t i; /* Boucle de parcours */
- printf("SYM ADDING>> '%s' @ 0x%08x\n", name, (unsigned int)virt);
+ result = true;
- routine = try_to_demangle_routine(name);
+ /* Charge tous les symboles définis dans une section */
+ void add_all_symbols_from_section(const elf_shdr *section, bool use_virt, GWorkQueue *wq, activity_id_t id)
+ {
+ phys_t start; /* Début de la zone à traiter */
+ phys_t size; /* Taille de cette même zone */
+ phys_t sym_size; /* Taille de chaque symbole lu */
+ guint runs_count; /* Qté d'exécutions parallèles */
+ phys_t run_size; /* Volume réparti par exécution*/
+ guint i; /* Boucle de parcours */
+ phys_t begin; /* Début de zone de traitement */
+ phys_t end; /* Fin d'un zone de traitement */
+ GElfLoading *loading; /* Tâche de chargement à lancer*/
- g_binary_routine_set_range(routine, &range);
+ get_elf_section_content(format, section, &start, &size, NULL);
- /* Symbole uniquement */
+ sym_size = ELF_SIZEOF_SYM(format);
- symbol = g_binary_symbol_new(STP_ROUTINE);
- g_binary_symbol_attach_routine(symbol, routine);
+ runs_count = g_get_num_processors();
- /* Comptabilisation pour le désassemblage brut */
+ run_size = size / (sym_size * runs_count);
- g_binary_format_register_code_point(base, virt, false);
+ gtk_status_stack_extend_activity(status, id, size / sym_size);
- break;
+ for (i = 0; i < runs_count; i++)
+ {
+ begin = start + i * run_size * sym_size;
- default:
- symbol = NULL;
- break;
+ if ((i + 1) == runs_count)
+ end = start + size;
+ else
+ end = begin + run_size * sym_size;
- }
+ loading = g_elf_loading_new(format, section, use_virt, start, begin, end,
+ id, do_elf_internal_symbol_loading);
- if (symbol != NULL)
- g_binary_format_add_symbol(base, symbol);
+ g_work_queue_schedule_work(wq, G_DELAYED_WORK(loading), gid);
}
- return true;
-
}
if (!g_generic_config_get_value(get_main_configuration(), MPK_FORMAT_NO_NAME, &no_name))
return false;
- if (find_elf_sections_by_type(format, SHT_DYNSYM, &sections, &count))
- for (i = 0; i < count && result; i++)
- result = add_all_symbols_from_section(format, &sections[i], no_name);
+ msg = gtk_status_stack_add_activity(status, _("Loading internal symbols..."), 0);
+
+ queue = get_work_queue();
+
+ if (find_elf_sections_by_type(format, SHT_DYNSYM, &dynsym_sections, &count))
+ for (i = 0; i < count; i++)
+ add_all_symbols_from_section(&dynsym_sections[i], no_name, queue, msg);
+
+ if (find_elf_sections_by_type(format, SHT_SYMTAB, &symtab_sections, &count))
+ for (i = 0; i < count; i++)
+ add_all_symbols_from_section(&symtab_sections[i], no_name, queue, msg);
+
+ g_work_queue_wait_for_completion(get_work_queue(), gid);
+
+ gtk_status_stack_remove_activity(status, msg);
- if (find_elf_sections_by_type(format, SHT_SYMTAB, &sections, &count))
- for (i = 0; i < count && result; i++)
- result = add_all_symbols_from_section(format, &sections[i], no_name);
+ if (dynsym_sections != NULL) free(dynsym_sections);
+ if (symtab_sections != NULL) free(symtab_sections);
return result;
diff --git a/src/format/elf/symbols.h b/src/format/elf/symbols.h
index 086cb0d..77ff373 100644
--- a/src/format/elf/symbols.h
+++ b/src/format/elf/symbols.h
@@ -28,8 +28,12 @@
#include "elf.h"
+#include "../../gtkext/gtkstatusstack.h"
+
+
+
/* Charge en mémoire la liste humaine des symboles. */
-bool load_elf_symbols(GElfFormat *);
+bool load_elf_symbols(GElfFormat *, GtkStatusStack *);
/* Récupère la définition complète d'un symbole donné. */
bool get_elf_symbol_by_index(GElfFormat *, const elf_shdr *, off_t, elf_sym *);
diff --git a/src/format/format-int.h b/src/format/format-int.h
index f8a7204..b19749d 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -57,6 +57,8 @@ struct _GBinFormat
size_t xp_allocated; /* Taille d'inscription allouée*/
size_t xp_count; /* Nombre de points enregistrés*/
+ GRWLock pt_lock; /* Accès à la liste des points */
+
GBinSymbol **symbols; /* Liste des symboles trouvés */
size_t symbols_count; /* Quantité de ces symboles */
GRWLock syms_lock; /* Accès à la liste de symboles*/
diff --git a/src/format/format.c b/src/format/format.c
index 1ee3001..ea67d2d 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -97,6 +97,8 @@ static void g_binary_format_class_init(GBinFormatClass *klass)
static void g_binary_format_init(GBinFormat *format)
{
+ g_rw_lock_init(&format->pt_lock);
+
g_rw_lock_init(&format->syms_lock);
}
@@ -212,6 +214,8 @@ SourceEndian g_binary_format_get_endianness(const GBinFormat *format)
void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool entry)
{
+ g_rw_lock_writer_lock(&format->pt_lock);
+
if (entry)
{
format->entry_points = (virt_t *)realloc(format->entry_points,
@@ -235,6 +239,8 @@ void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool ent
}
+ g_rw_lock_writer_unlock(&format->pt_lock);
+
}
@@ -251,16 +257,20 @@ void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool ent
* *
******************************************************************************/
-void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProcContext *ctx)
+void g_binary_format_setup_disassembling_context(GBinFormat *format, GProcContext *ctx)
{
size_t i; /* Boucle de parcours */
+ g_rw_lock_reader_lock(&format->pt_lock);
+
for (i = 0; i < format->ep_count; i++)
g_proc_context_push_drop_point(ctx, 0, format->entry_points[i]);
for (i = 0; i < format->xp_count; i++)
g_proc_context_push_drop_point(ctx, 0, format->extra_points[i]);
+ g_rw_lock_reader_unlock(&format->pt_lock);
+
}
diff --git a/src/format/format.h b/src/format/format.h
index 19c2b0a..e21e478 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -65,7 +65,7 @@ SourceEndian g_binary_format_get_endianness(const GBinFormat *);
void g_binary_format_register_code_point(GBinFormat *, virt_t, bool);
/* Fournit un contexte initialisé pour un désassemblage. */
-void g_binary_format_setup_disassembling_context(const GBinFormat *, GProcContext *);
+void g_binary_format_setup_disassembling_context(GBinFormat *, GProcContext *);
/* Ajoute un symbole à la collection du format binaire. */
void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);
diff --git a/src/glibext/delayed.c b/src/glibext/delayed.c
index 37b3ed7..f0aa141 100644
--- a/src/glibext/delayed.c
+++ b/src/glibext/delayed.c
@@ -814,7 +814,7 @@ static void g_work_queue_finalize(GWorkQueue *queue)
/******************************************************************************
* *
-* Paramètres : ref = espace de référencements global. *
+* Paramètres : status = barre de statut à tenir informée. *
* *
* Description : Procède au chargement du gestionnaire d'analyse différées. *
* *
@@ -824,19 +824,16 @@ static void g_work_queue_finalize(GWorkQueue *queue)
* *
******************************************************************************/
-bool init_work_queue(GObject *ref)
+bool init_work_queue(GtkStatusStack *status)
{
GWorkQueue *queue; /* Singleton à mettre en place */
queue = g_object_new(G_TYPE_WORK_QUEUE, NULL);
- if (ref != NULL)
- {
- queue->status = g_object_get_data(ref, "statusbar");
+ queue->status = status;
+
+ if (status != NULL)
g_object_ref(G_OBJECT(queue->status));
- }
- else
- queue->status = NULL;
if (queue != NULL)
_get_work_queue(queue);
diff --git a/src/glibext/delayed.h b/src/glibext/delayed.h
index 4902e68..14d54a1 100644
--- a/src/glibext/delayed.h
+++ b/src/glibext/delayed.h
@@ -30,6 +30,11 @@
+/* Abstration d'une gestion de barre de statut (instance) */
+typedef struct _GtkStatusStack GtkStatusStack;
+
+
+
/* -------------------------- TACHE DIFFEREE DANS LE TEMPS -------------------------- */
@@ -88,7 +93,7 @@ typedef unsigned long long wgroup_id_t;
GType g_work_queue_get_type(void);
/* Procède au chargement du gestionnaire d'analyse différées. */
-bool init_work_queue(GObject *);
+bool init_work_queue(GtkStatusStack *);
/* Fournit le gestionnaire de traitements parallèles courant. */
GWorkQueue *_get_work_queue(GWorkQueue *);
diff --git a/src/gtkext/gtkstatusstack.c b/src/gtkext/gtkstatusstack.c
index d84f179..95166d7 100644
--- a/src/gtkext/gtkstatusstack.c
+++ b/src/gtkext/gtkstatusstack.c
@@ -24,6 +24,7 @@
#include "gtkstatusstack.h"
+#include <assert.h>
#include <inttypes.h>
#include <malloc.h>
#include <string.h>
@@ -878,6 +879,43 @@ activity_id_t gtk_status_stack_add_activity(GtkStatusStack *stack, const char *m
}
+
+/******************************************************************************
+* *
+* Paramètres : stack = barre de statut à actualiser. *
+* id = identifiant de l'activité à cibler. *
+* extra = nouvelle échéance supplémentaire des traitements. *
+* *
+* Description : Etend la portée des travaux d'une nouvelle activité. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void gtk_status_stack_extend_activity(GtkStatusStack *stack, activity_id_t id, unsigned long extra)
+{
+ progress_info *info; /* Informations à consulter */
+ size_t i; /* Boucle de parcours */
+
+ info = stack->prog_info;
+
+ g_mutex_lock(&info->access);
+
+ for (i = 0; i < info->count; i++)
+ if (info->statuses[i].id == id)
+ break;
+
+ assert(i < info->count);
+
+ info->statuses[i].max += extra;
+
+ g_mutex_unlock(&info->access);
+
+}
+
+
/******************************************************************************
* *
* Paramètres : stack = barre de statut à actualiser. *
@@ -907,38 +945,36 @@ void gtk_status_stack_update_activity(GtkStatusStack *stack, activity_id_t id, c
if (info->statuses[i].id == id)
break;
- if (i < info->count)
- {
- /* Intitulé */
+ assert(i < info->count);
- if (info->statuses[i].message != NULL)
- {
- if (msg == NULL)
- msg_changed = true;
- else
- msg_changed = (strcmp(info->statuses[i].message, msg) != 0);
-
- free(info->statuses[i].message);
-
- }
- else
- msg_changed = (msg != NULL);
+ /* Intitulé */
+ if (info->statuses[i].message != NULL)
+ {
if (msg == NULL)
- info->statuses[i].message = NULL;
+ msg_changed = true;
else
- info->statuses[i].message = strdup(msg);
+ msg_changed = (strcmp(info->statuses[i].message, msg) != 0);
- /* On n'actualise que le sommet de la pile */
+ free(info->statuses[i].message);
- if ((i + 1) == info->count)
- {
- if (info->tag != 0)
- g_source_remove(info->tag);
+ }
+ else
+ msg_changed = (msg != NULL);
- info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack);
+ if (msg == NULL)
+ info->statuses[i].message = NULL;
+ else
+ info->statuses[i].message = strdup(msg);
- }
+ /* On n'actualise que le sommet de la pile */
+
+ if ((i + 1) == info->count)
+ {
+ if (info->tag != 0)
+ g_source_remove(info->tag);
+
+ info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack);
}
@@ -977,30 +1013,28 @@ void gtk_status_stack_update_activity_value(GtkStatusStack *stack, activity_id_t
if (info->statuses[i].id == id)
break;
- if (i < info->count)
- {
- status = &info->statuses[i];
+ assert(i < info->count);
- /* Valeur */
+ status = &info->statuses[i];
- status->current += inc;
+ /* Valeur */
- new = (status->current * 1.0) / status->max;
+ status->current += inc;
- /* On n'actualise que le sommet de la pile */
+ new = (status->current * 1.0) / status->max;
+ /* On n'actualise que le sommet de la pile */
- //fprintf(stderr, "PROG %g -> %g <=> %g ==> %d\n", old, new, new - old, (new - old) > 0.1);
+ //fprintf(stderr, "PROG %g -> %g <=> %g ==> %d\n", old, new, new - old, (new - old) > 0.1);
- if ((i + 1) == info->count && (new - status->last_updated) > 0.1)
- {
- if (info->tag != 0)
- g_source_remove(info->tag);
- info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack);
+ if ((i + 1) == info->count && (new - status->last_updated) > 0.1)
+ {
+ if (info->tag != 0)
+ g_source_remove(info->tag);
- }
+ info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack);
}
@@ -1034,40 +1068,38 @@ void gtk_status_stack_remove_activity(GtkStatusStack *stack, activity_id_t id)
if (info->statuses[i].id == id)
break;
- if (i < info->count)
- {
- if (info->tag != 0)
- g_source_remove(info->tag);
+ assert(i < info->count);
- if (info->statuses[i].message != NULL)
- free(info->statuses[i].message);
+ if (info->tag != 0)
+ g_source_remove(info->tag);
- if (info->count == 1)
- {
- free(info->statuses);
- info->statuses = NULL;
- }
- else
- {
- memmove(&info->statuses[i], &info->statuses[i + 1],
- (info->count - i - 1) * sizeof(progress_status));
+ if (info->statuses[i].message != NULL)
+ free(info->statuses[i].message);
- info->statuses = (progress_status *)realloc(info->statuses,
- (info->count - 1) * sizeof(progress_status));
+ if (info->count == 1)
+ {
+ free(info->statuses);
+ info->statuses = NULL;
+ }
+ else
+ {
+ memmove(&info->statuses[i], &info->statuses[i + 1],
+ (info->count - i - 1) * sizeof(progress_status));
- }
+ info->statuses = (progress_status *)realloc(info->statuses,
+ (info->count - 1) * sizeof(progress_status));
- info->count--;
+ }
- if (info->count == 0)
- {
- info->tag = 0;
- g_idle_add((GSourceFunc)gtk_status_stack_show_current_instruction, stack);
- }
- else
- info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack);
+ info->count--;
+ if (info->count == 0)
+ {
+ info->tag = 0;
+ g_idle_add((GSourceFunc)gtk_status_stack_show_current_instruction, stack);
}
+ else
+ info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack);
g_mutex_unlock(&info->access);
diff --git a/src/gtkext/gtkstatusstack.h b/src/gtkext/gtkstatusstack.h
index 590f562..1701d77 100644
--- a/src/gtkext/gtkstatusstack.h
+++ b/src/gtkext/gtkstatusstack.h
@@ -79,6 +79,9 @@ typedef unsigned long activity_id_t;
/* Démarre le suivi d'une nouvelle activité. */
activity_id_t gtk_status_stack_add_activity(GtkStatusStack *, const char *, unsigned long);
+/* Etend la portée des travaux d'une nouvelle activité. */
+void gtk_status_stack_extend_activity(GtkStatusStack *, activity_id_t, unsigned long);
+
/* Actualise les informations concernant une activité. */
void gtk_status_stack_update_activity(GtkStatusStack *, activity_id_t, const char *);
diff --git a/src/gui/core/Makefile.am b/src/gui/core/Makefile.am
index 2000f58..75b342f 100755
--- a/src/gui/core/Makefile.am
+++ b/src/gui/core/Makefile.am
@@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libguicore.la
libguicore_la_SOURCES = \
core.h core.c \
+ global.h global.c \
panels.h panels.c
libguicore_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS)
diff --git a/src/gui/core/global.c b/src/gui/core/global.c
new file mode 100644
index 0000000..10db31a
--- /dev/null
+++ b/src/gui/core/global.c
@@ -0,0 +1,68 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * global.c - conservation de variables globales à vocation graphique
+ *
+ * Copyright (C) 2016 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 "global.h"
+
+
+
+/* Barre de statut principale */
+static GtkStatusStack *_status = NULL;
+
+
+
+/******************************************************************************
+* *
+* Paramètres : status = barre de statut à tenir informée. *
+* *
+* Description : Note l'adresse de la barre de statut principale. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void set_global_status(GtkStatusStack *status)
+{
+ _status = status;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit l'adresse de la barre de statut principale. *
+* *
+* Retour : barre de statut à tenir informée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GtkStatusStack *get_global_status(void)
+{
+ return _status;
+
+}
diff --git a/src/gui/core/global.h b/src/gui/core/global.h
new file mode 100644
index 0000000..dfd5cc2
--- /dev/null
+++ b/src/gui/core/global.h
@@ -0,0 +1,40 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * global.h - prototypes pour la conservation de variables globales à vocation graphique
+ *
+ * Copyright (C) 2016 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 _GUI_CORE_GLOBAL_H
+#define _GUI_CORE_GLOBAL_H
+
+
+#include "../../gtkext/gtkstatusstack.h"
+
+
+
+/* Note l'adresse de la barre de statut principale. */
+void set_global_status(GtkStatusStack *);
+
+/* Fournit l'adresse de la barre de statut principale. */
+GtkStatusStack *get_global_status(void);
+
+
+
+#endif /* _GUI_CORE_GLOBAL_H */
diff --git a/src/gui/status.c b/src/gui/status.c
index f1171bd..0a3572a 100644
--- a/src/gui/status.c
+++ b/src/gui/status.c
@@ -34,6 +34,7 @@
#include "editem-int.h"
+#include "core/global.h"
#include "../common/extstr.h"
#include "../gtkext/gtkbufferview.h"
#include "../gtkext/gtkblockview.h"
@@ -199,7 +200,7 @@ GEditorItem *g_status_info_new(GObject *ref)
g_object_ref(ref);
item->ref = ref;
- g_object_set_data(ref, "statusbar", item->widget);
+ set_global_status(GTK_STATUS_STACK(item->widget));
return G_EDITOR_ITEM(result);
diff --git a/src/main.c b/src/main.c
index ec379bc..821773d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -38,6 +38,7 @@
#include "gtkext/theme.h"
#include "gui/editor.h"
#include "gui/core/core.h"
+#include "gui/core/global.h"
#include "plugins/pglist.h"
@@ -172,7 +173,7 @@ int main(int argc, char **argv)
editor = create_editor();
gtk_widget_show_now(editor);
- init_work_queue(G_OBJECT(editor));
+ init_work_queue(get_global_status());
init_all_plugins(G_OBJECT(editor));