diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-05-19 21:21:30 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-05-19 21:21:30 (GMT) |
commit | f828d126a74facac145531822c6ea9c8259b50e0 (patch) | |
tree | 521bfa44de551f30934ee321339a7a87d12a3243 /src/format | |
parent | e92c777c91612c8508d263645480c6c3889b679d (diff) |
Loaded the ELF internal symbols using all the available CPUs.
Diffstat (limited to 'src/format')
-rwxr-xr-x | src/format/dex/dex.c | 3 | ||||
-rwxr-xr-x | src/format/dex/dex.h | 2 | ||||
-rw-r--r-- | src/format/dwarf/v2/dwarf.c | 3 | ||||
-rw-r--r-- | src/format/dwarf/v2/dwarf.h | 2 | ||||
-rw-r--r-- | src/format/dwarf/v3/dwarf.c | 3 | ||||
-rw-r--r-- | src/format/dwarf/v3/dwarf.h | 2 | ||||
-rw-r--r-- | src/format/dwarf/v4/dwarf.c | 3 | ||||
-rw-r--r-- | src/format/dwarf/v4/dwarf.h | 2 | ||||
-rw-r--r-- | src/format/elf/Makefile.am | 1 | ||||
-rw-r--r-- | src/format/elf/elf.c | 5 | ||||
-rw-r--r-- | src/format/elf/elf.h | 2 | ||||
-rw-r--r-- | src/format/elf/loading.c | 291 | ||||
-rw-r--r-- | src/format/elf/loading.h | 71 | ||||
-rw-r--r-- | src/format/elf/symbols.c | 328 | ||||
-rw-r--r-- | src/format/elf/symbols.h | 6 | ||||
-rw-r--r-- | src/format/format-int.h | 2 | ||||
-rw-r--r-- | src/format/format.c | 12 | ||||
-rw-r--r-- | src/format/format.h | 2 |
18 files changed, 603 insertions, 137 deletions
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, §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 *); |