From f828d126a74facac145531822c6ea9c8259b50e0 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 19 May 2016 23:21:30 +0200 Subject: Loaded the ELF internal symbols using all the available CPUs. --- ChangeLog | 66 ++++++++ plugins/mobicore/mclf.c | 3 +- plugins/mobicore/mclf.h | 2 +- plugins/pychrysa/format/elf/elf.c | 2 +- src/analysis/disass/instructions.c | 14 +- src/analysis/disass/routines.c | 14 +- src/core/formats.c | 8 +- src/core/formats.h | 3 +- src/format/dex/dex.c | 3 +- src/format/dex/dex.h | 2 +- src/format/dwarf/v2/dwarf.c | 3 +- src/format/dwarf/v2/dwarf.h | 2 +- src/format/dwarf/v3/dwarf.c | 3 +- src/format/dwarf/v3/dwarf.h | 2 +- src/format/dwarf/v4/dwarf.c | 3 +- src/format/dwarf/v4/dwarf.h | 2 +- src/format/elf/Makefile.am | 1 + src/format/elf/elf.c | 5 +- src/format/elf/elf.h | 2 +- src/format/elf/loading.c | 291 ++++++++++++++++++++++++++++++++ src/format/elf/loading.h | 71 ++++++++ src/format/elf/symbols.c | 328 +++++++++++++++++++++++-------------- src/format/elf/symbols.h | 6 +- src/format/format-int.h | 2 + src/format/format.c | 12 +- src/format/format.h | 2 +- src/glibext/delayed.c | 13 +- src/glibext/delayed.h | 7 +- src/gtkext/gtkstatusstack.c | 160 ++++++++++-------- src/gtkext/gtkstatusstack.h | 3 + src/gui/core/Makefile.am | 1 + src/gui/core/global.c | 68 ++++++++ src/gui/core/global.h | 40 +++++ src/gui/status.c | 3 +- src/main.c | 3 +- 35 files changed, 919 insertions(+), 231 deletions(-) create mode 100644 src/format/elf/loading.c create mode 100644 src/format/elf/loading.h create mode 100644 src/gui/core/global.c create mode 100644 src/gui/core/global.h diff --git a/ChangeLog b/ChangeLog index 3b5eb64..95bc008 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,69 @@ +16-05-19 Cyrille Bagard + + * plugins/mobicore/mclf.c: + * plugins/mobicore/mclf.h: + * plugins/pychrysa/format/elf/elf.c: + Update code. + + * src/analysis/disass/instructions.c: + * src/analysis/disass/routines.c: + Typo. + + * src/core/formats.c: + * src/core/formats.h: + Use the global status bar to load binary formats. + + * src/format/dex/dex.c: + * src/format/dex/dex.h: + * src/format/dwarf/v2/dwarf.c: + * src/format/dwarf/v2/dwarf.h: + * src/format/dwarf/v3/dwarf.c: + * src/format/dwarf/v3/dwarf.h: + * src/format/dwarf/v4/dwarf.c: + * src/format/dwarf/v4/dwarf.h: + Update code. + + * src/format/elf/Makefile.am: + Add the 'loading.[ch]' files to libformatelf_la_SOURCES. + + * src/format/elf/elf.c: + * src/format/elf/elf.h: + Update code. + + * src/format/elf/loading.c: + * src/format/elf/loading.h: + New entries: display some progress information while loading ELF symbols. + + * src/format/elf/symbols.c: + * src/format/elf/symbols.h: + Load the ELF internal symbols using all the available CPUs. + + * src/format/format-int.h: + * src/format/format.c: + * src/format/format.h: + Avoid memory corruptions using locks. + + * src/glibext/delayed.c: + * src/glibext/delayed.h: + Update code. + + * src/gtkext/gtkstatusstack.c: + * src/gtkext/gtkstatusstack.h: + Define extendable activities. Update code. + + * src/gui/core/Makefile.am: + Add the 'global.[ch]' files to libguicore_la_SOURCES. + + * src/gui/core/global.c: + * src/gui/core/global.h: + New entries: define and provide global GUI references. + + * src/gui/status.c: + Register the global status bar. + + * src/main.c: + Update code. + 16-05-13 Cyrille Bagard * src/glibext/gbufferview.c: diff --git a/plugins/mobicore/mclf.c b/plugins/mobicore/mclf.c index 8e99fc7..6ff967b 100644 --- a/plugins/mobicore/mclf.c +++ b/plugins/mobicore/mclf.c @@ -193,6 +193,7 @@ static void g_mclf_format_finalize(GMCLFFormat *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 MCLF. * * * @@ -202,7 +203,7 @@ static void g_mclf_format_finalize(GMCLFFormat *format) * * ******************************************************************************/ -GBinFormat *g_mclf_format_new(GBinContent *content, GExeFormat *parent) +GBinFormat *g_mclf_format_new(GBinContent *content, GExeFormat *parent, GtkStatusStack *status) { GMCLFFormat *result; /* Structure à retourner */ diff --git a/plugins/mobicore/mclf.h b/plugins/mobicore/mclf.h index 78ed57b..a8fe6ea 100644 --- a/plugins/mobicore/mclf.h +++ b/plugins/mobicore/mclf.h @@ -58,7 +58,7 @@ FormatMatchStatus mclf_is_matching(GBinContent *, GExeFormat *, void *, char **) GType g_mclf_format_get_type(void); /* Prend en charge un nouveau format MCLF. */ -GBinFormat *g_mclf_format_new(GBinContent *, GExeFormat *); +GBinFormat *g_mclf_format_new(GBinContent *, GExeFormat *, GtkStatusStack *); diff --git a/plugins/pychrysa/format/elf/elf.c b/plugins/pychrysa/format/elf/elf.c index 72a9647..2787702 100644 --- a/plugins/pychrysa/format/elf/elf.c +++ b/plugins/pychrysa/format/elf/elf.c @@ -77,7 +77,7 @@ static PyObject *py_elf_format_new(PyTypeObject *type, PyObject *args, PyObject } content = G_BIN_CONTENT(pygobject_get(content_obj)); - format = g_elf_format_new(content, NULL); + format = g_elf_format_new(content, NULL, NULL/*FIXME*/); result = pygobject_new(G_OBJECT(format)); 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 . + */ + + +#include "loading.h" + + +#include + + +#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 . + */ + + +#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, §ion, &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, §ions, &count)) - for (i = 0; i < count && result; i++) - result = add_all_symbols_from_section(format, §ions[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, §ions, &count)) - for (i = 0; i < count && result; i++) - result = add_all_symbols_from_section(format, §ions[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 #include #include #include @@ -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 . + */ + + +#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 . + */ + + +#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)); -- cgit v0.11.2-87-g4458