summaryrefslogtreecommitdiff
path: root/src/format/elf
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-05-19 21:21:30 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-05-19 21:21:30 (GMT)
commitf828d126a74facac145531822c6ea9c8259b50e0 (patch)
tree521bfa44de551f30934ee321339a7a87d12a3243 /src/format/elf
parente92c777c91612c8508d263645480c6c3889b679d (diff)
Loaded the ELF internal symbols using all the available CPUs.
Diffstat (limited to 'src/format/elf')
-rw-r--r--src/format/elf/Makefile.am1
-rw-r--r--src/format/elf/elf.c5
-rw-r--r--src/format/elf/elf.h2
-rw-r--r--src/format/elf/loading.c291
-rw-r--r--src/format/elf/loading.h71
-rw-r--r--src/format/elf/symbols.c328
-rw-r--r--src/format/elf/symbols.h6
7 files changed, 577 insertions, 127 deletions
diff --git a/src/format/elf/Makefile.am b/src/format/elf/Makefile.am
index 4317e1d..78dabcd 100644
--- a/src/format/elf/Makefile.am
+++ b/src/format/elf/Makefile.am
@@ -8,6 +8,7 @@ libformatelf_la_SOURCES = \
dynamic.h dynamic.c \
helper_arm.h helper_arm.c \
helper_x86.h helper_x86.c \
+ loading.h loading.c \
program.h program.c \
section.h section.c \
strings.h strings.c \
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index 0c7760c..d09b845 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -230,6 +230,7 @@ static void g_elf_format_finalize(GElfFormat *format)
* *
* Paramètres : content = contenu binaire à parcourir. *
* parent = éventuel format exécutable déjà chargé. *
+ status = barre de statut à tenir informée. *
* *
* Description : Prend en charge un nouveau format ELF. *
* *
@@ -239,7 +240,7 @@ static void g_elf_format_finalize(GElfFormat *format)
* *
******************************************************************************/
-GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent)
+GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatusStack *status)
{
GElfFormat *result; /* Structure à retourner */
@@ -287,7 +288,7 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent)
- if (!load_elf_symbols(result))
+ if (!load_elf_symbols(result, status))
{
/* TODO */
return NULL;
diff --git a/src/format/elf/elf.h b/src/format/elf/elf.h
index d6f631e..3343927 100644
--- a/src/format/elf/elf.h
+++ b/src/format/elf/elf.h
@@ -56,7 +56,7 @@ FormatMatchStatus elf_is_matching(GBinContent *, GExeFormat *, void *, char **);
GType g_elf_format_get_type(void);
/* Prend en charge un nouveau format ELF. */
-GBinFormat *g_elf_format_new(GBinContent *, GExeFormat *);
+GBinFormat *g_elf_format_new(GBinContent *, GExeFormat *, GtkStatusStack *);
/* Présente l'en-tête ELF du format chargé. */
const elf_header *g_elf_format_get_header(const GElfFormat *);
diff --git a/src/format/elf/loading.c b/src/format/elf/loading.c
new file mode 100644
index 0000000..b833720
--- /dev/null
+++ b/src/format/elf/loading.c
@@ -0,0 +1,291 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loading.c - chargements parallèles des symboles de format ELF
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "loading.h"
+
+
+#include <i18n.h>
+
+
+#include "elf-int.h"
+#include "section.h"
+#include "../../glibext/delayed-int.h"
+#include "../../gui/panels/log.h"
+
+
+
+/* Fraction de routines à limiter (instance) */
+struct _GElfLoading
+{
+ GDelayedWork parent; /* A laisser en premier */
+
+ GElfFormat *format; /* Format à faire évoluer */
+
+ union
+ {
+ struct
+ {
+ const elf_shdr *section; /* Section à éplucher */
+ bool use_virt; /* Représentatio par défaut */
+
+ elf_shdr strtab; /* Section .strtab trouvée */
+ bool has_strtab; /* Présence de cette section */
+
+ };
+
+ };
+
+ elf_loading_cb callback; /* Routine de traitement finale*/
+ phys_t first; /* Position du premier élément */
+ phys_t begin; /* Point de départ du parcours */
+ phys_t end; /* Point d'arrivée exclu */
+
+ activity_id_t id; /* Identifiant pour messages */
+
+};
+
+/* Fraction de routines à limiter (classe) */
+struct _GElfLoadingClass
+{
+ GDelayedWorkClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des tâches des chargements pour ELF. */
+static void g_elf_loading_class_init(GElfLoadingClass *);
+
+/* Initialise une tâche de chargements pour ELF. */
+static void g_elf_loading_init(GElfLoading *);
+
+/* Supprime toutes les références externes. */
+static void g_elf_loading_dispose(GElfLoading *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_elf_loading_finalize(GElfLoading *);
+
+/* Assure le chargement pour un format ELF en différé. */
+static void g_elf_loading_process(GElfLoading *, GtkStatusStack *);
+
+
+
+/* Indique le type défini pour les tâches de chargements pour format ELF. */
+G_DEFINE_TYPE(GElfLoading, g_elf_loading, G_TYPE_DELAYED_WORK);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des tâches des chargements pour ELF. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_loading_class_init(GElfLoadingClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GDelayedWorkClass *work; /* Version en classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_elf_loading_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_elf_loading_finalize;
+
+ work = G_DELAYED_WORK_CLASS(klass);
+
+ work->run = (run_task_fc)g_elf_loading_process;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : loading = instance à initialiser. *
+* *
+* Description : Initialise une tâche de chargements pour ELF. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_loading_init(GElfLoading *loading)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : loading = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_loading_dispose(GElfLoading *loading)
+{
+ G_OBJECT_CLASS(g_elf_loading_parent_class)->dispose(G_OBJECT(loading));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : loading = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_loading_finalize(GElfLoading *loading)
+{
+ G_OBJECT_CLASS(g_elf_loading_parent_class)->finalize(G_OBJECT(loading));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = = ensemble d'instructions désassemblées. *
+* section = prototypes existants à insérer. *
+* use_virt = quantité de ces prototypes. *
+* first = position du premier élément. *
+* begin = point de départ du parcours de liste. *
+* end = point d'arrivée exclu du parcours. *
+* id = identifiant du message affiché à l'utilisateur. *
+* callback = routine de traitements particuliers. *
+* *
+* Description : Crée une tâche de chargement pour ELF différée. *
+* *
+* Retour : Tâche créée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GElfLoading *g_elf_loading_new(GElfFormat *format, const elf_shdr *section, bool use_virt, phys_t first, phys_t begin, phys_t end, activity_id_t id, elf_loading_cb callback)
+{
+ GElfLoading *result; /* Tâche à retourner */
+
+ result = g_object_new(G_TYPE_ELF_LOADING, NULL);
+
+ result->format = format;
+
+ result->section = section;
+ result->use_virt = use_virt;
+
+ result->has_strtab = find_elf_section_by_index(format,
+ ELF_SHDR(format, *section, sh_link),
+ &result->strtab);
+
+ result->callback = callback;
+ result->first = first;
+ result->begin = begin;
+ result->end = end;
+
+ result->id = id;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : study = étude de routines à mener. *
+* status = barre de statut à tenir informée. *
+* *
+* Description : Assure le chargement pour un format ELF en différé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_loading_process(GElfLoading *loading, GtkStatusStack *status)
+{
+ phys_t iter; /* Boucle de parcours */
+ phys_t old; /* Sauvegarde du point d'avant */
+ bool ret; /* Bilan d'un appel */
+
+ for (iter = loading->begin; iter < loading->end; )
+ {
+ old = iter;
+ ret = loading->callback(loading, loading->format, &iter);
+
+ if (!ret)
+ {
+ log_variadic_message(LMT_ERROR, _("Error while loading ELF data @ 0x%08x!"), old);
+ break;
+ }
+
+ gtk_status_stack_update_activity_value(status, loading->id, 1);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : loading = chargement pour ELF à mener. *
+* section = prototypes existants à insérer. [OUT] *
+* use_virt = quantité de ces prototypes. [OUT] *
+* strtab = informations quant à la table des chaînes. [OUT]*
+* has_strtab = validité du champ précédemment renseigné. [OUT] *
+* first = position du premier élément. [OUT] *
+* *
+* Description : Fournit les infos utiles au chargement de symbols internes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_elf_loading_get_internal_info(GElfLoading *loading, const elf_shdr **section, bool *use_virt, const elf_shdr **strtab, bool *has_strtab, phys_t *first)
+{
+ *section = loading->section;
+ *use_virt = loading->use_virt;
+
+ *strtab = &loading->strtab;
+ *has_strtab = loading->has_strtab;
+
+ *first = loading->first;
+
+}
diff --git a/src/format/elf/loading.h b/src/format/elf/loading.h
new file mode 100644
index 0000000..ac7701f
--- /dev/null
+++ b/src/format/elf/loading.h
@@ -0,0 +1,71 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loading.h - prototypes pour les chargements parallèles des symboles de format ELF
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _FORMAT_ELF_LOADING_H
+#define _FORMAT_ELF_LOADING_H
+
+
+#include "elf.h"
+#include "../../gtkext/gtkstatusstack.h"
+
+
+
+
+//#include "../routine.h"
+//#include "../../arch/processor.h"
+//#include "../../format/executable.h"
+//#include "../../gtkext/gtkstatusstack.h"
+
+
+
+#define G_TYPE_ELF_LOADING g_elf_loading_get_type()
+#define G_ELF_LOADING(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_elf_loading_get_type(), GElfLoading))
+#define G_IS_ELF_LOADING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_elf_loading_get_type()))
+#define G_ELF_LOADING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ELF_LOADING, GElfLoadingClass))
+#define G_IS_ELF_LOADING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ELF_LOADING))
+#define G_ELF_LOADING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ELF_LOADING, GElfLoadingClass))
+
+
+/* Fraction de loading à limiter (instance) */
+typedef struct _GElfLoading GElfLoading;
+
+/* Fraction de loading à limiter (classe) */
+typedef struct _GElfLoadingClass GElfLoadingClass;
+
+
+/* Assure un chargement pour ELF en différé. */
+typedef bool (* elf_loading_cb) (GElfLoading *, GElfFormat *, phys_t *);
+
+
+/* Indique le type défini pour les tâches de chargements pour format ELF. */
+GType g_elf_loading_get_type(void);
+
+/* Crée une tâche de chargement pour ELF différée. */
+GElfLoading *g_elf_loading_new(GElfFormat *, const elf_shdr *, bool, phys_t, phys_t, phys_t, activity_id_t, elf_loading_cb);
+
+/* Fournit les infos utiles au chargement de symbols internes. */
+void g_elf_loading_get_internal_info(GElfLoading *, const elf_shdr **, bool *, const elf_shdr **, bool *, phys_t *);
+
+
+
+#endif /* _FORMAT_ELF_LOADING_H */
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index 29a8c3c..cfd0a09 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -36,6 +36,7 @@
#include "elf-int.h"
#include "helper_arm.h"
#include "helper_x86.h"
+#include "loading.h"
#include "program.h"
#include "section.h"
#include "../mangling/demangler.h"
@@ -47,6 +48,12 @@
+
+
+
+
+
+
/* Enregistre un point d'entrée au sein d'un binaire ELF. */
static void register_elf_entry_point(GElfFormat *, virt_t, phys_t, GBinRoutine *);
@@ -64,8 +71,11 @@ static bool load_all_elf_basic_entry_points(GElfFormat *);
/* -------------------------- DETAIL DES SYMBOLES INTERNES -------------------------- */
+/* Assure le chargement des symboles internes ELF en différé. */
+static bool do_elf_internal_symbol_loading(GElfLoading *, GElfFormat *, phys_t *);
+
/* Charge tous les symboles internes possibles. */
-static bool load_elf_internal_symbols(GElfFormat *);
+static bool load_elf_internal_symbols(GElfFormat *, wgroup_id_t, GtkStatusStack *);
@@ -87,9 +97,13 @@ static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *);
+
+
+
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+ status = barre de statut à tenir informée. *
* *
* Description : Charge en mémoire la liste humaine des symboles. *
* *
@@ -99,18 +113,21 @@ static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *);
* *
******************************************************************************/
-bool load_elf_symbols(GElfFormat *format)
+bool load_elf_symbols(GElfFormat *format, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
+ wgroup_id_t gid; /* Identifiant pour les tâches */
elf_shdr *sections; /* Groupe de sections trouvées */
size_t count; /* Quantité de données */
result = true;
+ gid = g_work_queue_define_work_group(get_work_queue());
+
/* Symboles internes */
- result &= load_elf_internal_symbols(format);
+ result &= load_elf_internal_symbols(format, gid, status);
@@ -150,6 +167,9 @@ bool load_elf_symbols(GElfFormat *format)
}
+
+
+
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
@@ -493,200 +513,262 @@ const char *get_elf_symbol_name(GElfFormat *format, const elf_shdr *sym, const e
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à compléter. *
+* Paramètres : loading = chargement de symboles internes en cours. *
+* format = format ELF à compléter. *
+* iter = tête de lecture évoluant avec le temps. [OUT] *
* *
-* Description : Charge tous les symboles internes possibles. *
+* Description : Assure le chargement des symboles internes ELF en différé. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool load_elf_internal_symbols(GElfFormat *format)
+static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *format, phys_t *iter)
{
bool result; /* Bilan à retourner */
- bool no_name; /* Choix de construction de nom*/
- elf_shdr *sections; /* Groupe de sections trouvées */
- size_t count; /* Quantité de données */
- size_t i; /* Boucle de parcours */
+ elf_sym sym; /* Symbole aux infos visées */
+ virt_t virt; /* Adresse virtuelle */
+ const elf_shdr *section; /* Groupe de sections trouvées */
+ bool use_virt; /* Choix de construction de nom*/
+ const elf_shdr *strtab; /* Section .strtab trouvée */
+ bool has_strtab; /* Présence de cette section */
+ phys_t first; /* Position du premier élément */
+ const char *name; /* Nom du symbole trouvé */
+ GBinFormat *base; /* Version basique du format */
+ vmpa2t addr; /* Localisation d'une routine */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
+ char alt_name[6 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/
+ virt_t final_virt; /* Adresse virtuelle retenue */
+ mrange_t range; /* Couverture mémoire associée */
+ GBinRoutine *routine; /* Nouvelle routine trouvée */
- result = true;
+ result = read_elf_symbol(format, iter, &sym);
+ if (!result) goto geslp_done;
- /* Charge tous les symboles définis dans une section */
- bool add_all_symbols_from_section(GElfFormat *format, const elf_shdr *section, bool use_virt)
- {
- GBinFormat *base; /* Version basique du format */
- elf_shdr strtab; /* Section .strtab trouvée */
- bool has_strtab; /* Présence de cette section */
- phys_t start; /* Début de la zone à traiter */
- phys_t size; /* Taille de cette même zone */
- phys_t iter; /* Boucle de parcours */
- elf_sym sym; /* Symbole aux infos visées */
- virt_t virt; /* Adresse virtuelle */
- virt_t final_virt; /* Adresse virtuelle retenue */
- vmpa2t addr; /* Localisation d'une routine */
- mrange_t range; /* Couverture mémoire associée */
- const char *name; /* Nom du symbole trouvé */
- char alt_name[6 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/
- GBinRoutine *routine; /* Nouvelle routine trouvée */
- GBinSymbol *symbol; /* Nouveau symbole construit */
+ /* On rejette les symboles qui ne sont pas définis au sein du binaire */
- base = G_BIN_FORMAT(format);
+ if (ELF_SYM(format, sym, st_shndx) == 0) goto geslp_done;
- has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, *section, sh_link), &strtab);
+ /* Résolution précise d'adresse */
- get_elf_section_content(format, section, &start, &size, NULL);
+ virt = ELF_SYM(format, sym, st_value);
+ if (virt == 0) goto geslp_done;
- for (iter = start; iter < (start + size); )
- {
- result = read_elf_symbol(format, &iter, &sym);
- if (!result) break;
- /* On rejette les symboles qui ne sont pas définis au sein du binaire */
- if (ELF_SYM(format, sym, st_shndx) == 0) continue;
+ /* TODO */
-#if 0
+ //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value));
- Elf64_Word st_name; /* Symbol name (string tbl index) */
- unsigned char st_info; /* Symbol type and binding */
- unsigned char st_other; /* Symbol visibility */
- Elf64_Section st_shndx; /* Section index */
- Elf64_Addr st_value; /* Symbol value */
- Elf64_Xword st_size; /* Symbol size */
-#endif
+ //init_mrange(&range, &addr, 0);
- if (ELF_SYM(format, sym, st_value) == 0) continue;
+ /* Première ébauche de nom */
- /* Résolution précise d'adresse */
+ g_elf_loading_get_internal_info(loading, &section, &use_virt, &strtab, &has_strtab, &first);
+ if (!has_strtab)
+ name = NULL;
- /* TODO */
+ else
+ name = get_elf_symbol_name(format, section, strtab,
+ ((*iter - first) / ELF_SIZEOF_SYM(format)) - 1);
- //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value));
+ /* Traitements particuliers */
- virt = ELF_SYM(format, sym, st_value);
+ base = G_BIN_FORMAT(format);
- //init_mrange(&range, &addr, 0);
+ switch (ELF_ST_TYPE(format, sym))
+ {
+ case STT_OBJECT:
+ /* Ajustement de la position */
- /* Première ébauche de nom */
+ if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr))
+ {
+ symbol = NULL;
+ break;
+ }
- if (!has_strtab) name = NULL;
- else name = get_elf_symbol_name(format, section, &strtab,
- ((iter - start) / ELF_SIZEOF_SYM(format)) - 1);
+ /* Création d'un nom unique ? */
- /* Traitements particuliers */
+ if (name == NULL)
+ {
+ strcpy(alt_name, "obj_");
- switch (ELF_ST_TYPE(format, sym))
+ if (use_virt)
+ vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL);
+ else
+ vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL);
+
+ name = alt_name;
+
+ }
+
+
+ /* TODO */
+
+ symbol = NULL;
+
+
+ break;
+
+ case STT_FUNC:
+
+ /* Ajustement de la position */
+
+ if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
+ final_virt = virt & ~0x1;
+ else
+ final_virt = virt;
+
+ if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr))
{
- case STT_OBJECT:
+ symbol = NULL;
+ break;
+ }
- /* Ajustement de la position */
+ init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
- if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr))
- {
- symbol = NULL;
- break;
- }
+ /* Création d'un nom unique ? */
- /* Création d'un nom unique ? */
+ if (name == NULL)
+ {
+ strcpy(alt_name, "func_");
- if (name != NULL)
- {
- strcpy(alt_name, "obj_");
+ if (use_virt)
+ vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL);
+ else
+ vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL);
- if (use_virt)
- vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL);
- else
- vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL);
+ name = alt_name;
- }
+ }
+ /* Routine */
- /* TODO */
+ routine = try_to_demangle_routine(name);
- symbol = NULL;
+ g_binary_routine_set_range(routine, &range);
+ /* Symbole uniquement */
- break;
+ symbol = g_binary_symbol_new(STP_ROUTINE);
+ g_binary_symbol_attach_routine(symbol, routine);
- case STT_FUNC:
+ /* Comptabilisation pour le désassemblage brut */
- /* Ajustement de la position */
+ g_binary_format_register_code_point(G_BIN_FORMAT(format), virt, false);
- if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
- final_virt = virt & ~0x1;
- else
- final_virt = virt;
+ break;
- if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr))
- {
- symbol = NULL;
- break;
- }
+ default:
+ symbol = NULL;
+ break;
- init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
+ }
- /* Création d'un nom unique ? */
+ if (symbol != NULL)
+ g_binary_format_add_symbol(base, symbol);
- if (name != NULL)
- {
- strcpy(alt_name, "func_");
+ geslp_done:
- if (use_virt)
- vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL);
- else
- vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL);
+ return result;
- }
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* gid = groupe de travail impliqué. *
+ status = barre de statut à tenir informée. *
+* *
+* Description : Charge tous les symboles internes possibles. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- /* Routine */
+static bool load_elf_internal_symbols(GElfFormat *format, wgroup_id_t gid, GtkStatusStack *status)
+{
+ bool result; /* Bilan à retourner */
+ bool no_name; /* Choix de construction de nom*/
+ activity_id_t msg; /* Message de progression */
+ GWorkQueue *queue; /* Gestionnaire de différés */
+ elf_shdr *dynsym_sections; /* Groupe de sections trouvées */
+ size_t count; /* Quantité de données */
+ elf_shdr *symtab_sections; /* Groupe de sections trouvées */
+ size_t i; /* Boucle de parcours */
- printf("SYM ADDING>> '%s' @ 0x%08x\n", name, (unsigned int)virt);
+ result = true;
- routine = try_to_demangle_routine(name);
+ /* Charge tous les symboles définis dans une section */
+ void add_all_symbols_from_section(const elf_shdr *section, bool use_virt, GWorkQueue *wq, activity_id_t id)
+ {
+ phys_t start; /* Début de la zone à traiter */
+ phys_t size; /* Taille de cette même zone */
+ phys_t sym_size; /* Taille de chaque symbole lu */
+ guint runs_count; /* Qté d'exécutions parallèles */
+ phys_t run_size; /* Volume réparti par exécution*/
+ guint i; /* Boucle de parcours */
+ phys_t begin; /* Début de zone de traitement */
+ phys_t end; /* Fin d'un zone de traitement */
+ GElfLoading *loading; /* Tâche de chargement à lancer*/
- g_binary_routine_set_range(routine, &range);
+ get_elf_section_content(format, section, &start, &size, NULL);
- /* Symbole uniquement */
+ sym_size = ELF_SIZEOF_SYM(format);
- symbol = g_binary_symbol_new(STP_ROUTINE);
- g_binary_symbol_attach_routine(symbol, routine);
+ runs_count = g_get_num_processors();
- /* Comptabilisation pour le désassemblage brut */
+ run_size = size / (sym_size * runs_count);
- g_binary_format_register_code_point(base, virt, false);
+ gtk_status_stack_extend_activity(status, id, size / sym_size);
- break;
+ for (i = 0; i < runs_count; i++)
+ {
+ begin = start + i * run_size * sym_size;
- default:
- symbol = NULL;
- break;
+ if ((i + 1) == runs_count)
+ end = start + size;
+ else
+ end = begin + run_size * sym_size;
- }
+ loading = g_elf_loading_new(format, section, use_virt, start, begin, end,
+ id, do_elf_internal_symbol_loading);
- if (symbol != NULL)
- g_binary_format_add_symbol(base, symbol);
+ g_work_queue_schedule_work(wq, G_DELAYED_WORK(loading), gid);
}
- return true;
-
}
if (!g_generic_config_get_value(get_main_configuration(), MPK_FORMAT_NO_NAME, &no_name))
return false;
- if (find_elf_sections_by_type(format, SHT_DYNSYM, &sections, &count))
- for (i = 0; i < count && result; i++)
- result = add_all_symbols_from_section(format, &sections[i], no_name);
+ msg = gtk_status_stack_add_activity(status, _("Loading internal symbols..."), 0);
+
+ queue = get_work_queue();
+
+ if (find_elf_sections_by_type(format, SHT_DYNSYM, &dynsym_sections, &count))
+ for (i = 0; i < count; i++)
+ add_all_symbols_from_section(&dynsym_sections[i], no_name, queue, msg);
+
+ if (find_elf_sections_by_type(format, SHT_SYMTAB, &symtab_sections, &count))
+ for (i = 0; i < count; i++)
+ add_all_symbols_from_section(&symtab_sections[i], no_name, queue, msg);
+
+ g_work_queue_wait_for_completion(get_work_queue(), gid);
+
+ gtk_status_stack_remove_activity(status, msg);
- if (find_elf_sections_by_type(format, SHT_SYMTAB, &sections, &count))
- for (i = 0; i < count && result; i++)
- result = add_all_symbols_from_section(format, &sections[i], no_name);
+ if (dynsym_sections != NULL) free(dynsym_sections);
+ if (symtab_sections != NULL) free(symtab_sections);
return result;
diff --git a/src/format/elf/symbols.h b/src/format/elf/symbols.h
index 086cb0d..77ff373 100644
--- a/src/format/elf/symbols.h
+++ b/src/format/elf/symbols.h
@@ -28,8 +28,12 @@
#include "elf.h"
+#include "../../gtkext/gtkstatusstack.h"
+
+
+
/* Charge en mémoire la liste humaine des symboles. */
-bool load_elf_symbols(GElfFormat *);
+bool load_elf_symbols(GElfFormat *, GtkStatusStack *);
/* Récupère la définition complète d'un symbole donné. */
bool get_elf_symbol_by_index(GElfFormat *, const elf_shdr *, off_t, elf_sym *);