summaryrefslogtreecommitdiff
path: root/plugins/elf/loading.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/elf/loading.c')
-rw-r--r--plugins/elf/loading.c120
1 files changed, 83 insertions, 37 deletions
diff --git a/plugins/elf/loading.c b/plugins/elf/loading.c
index 5bd7daa..bf79f13 100644
--- a/plugins/elf/loading.c
+++ b/plugins/elf/loading.c
@@ -75,6 +75,8 @@ struct _GElfLoading
phys_t sym_start; /* Début de zone des symboles */
uint32_t sym_count; /* Nombre de symboles présents */
+ GBinSymbol **imports_to_fill; /* Liste de symboles constitués*/
+
};
struct
@@ -107,9 +109,9 @@ struct _GElfLoading
struct
{
- sym_iter_t *iter; /* Symboles à parcourir */
+ vmpa2t start; /* Point de départ du parcours */
- elf_applying_cb callback_1; /* Routine de traitement #1 */
+ elf_importing_cb callback_1; /* Routine de traitement #1 */
};
@@ -213,7 +215,13 @@ static void g_elf_loading_init(GElfLoading *loading)
static void g_elf_loading_dispose(GElfLoading *loading)
{
- if (loading->kind == 2)
+ size_t i; /* Boucle de parcours */
+
+ if (loading->kind == 1)
+ for (i = 0; i < loading->rel_count; i++)
+ g_clear_object(&loading->imports_to_fill[i]);
+
+ else if (loading->kind == 2)
g_clear_object(&loading->content);
G_OBJECT_CLASS(g_elf_loading_parent_class)->dispose(G_OBJECT(loading));
@@ -336,7 +344,7 @@ GElfLoading *g_elf_loading_new_for_relocations(GElfFormat *format, phys_t begin,
/******************************************************************************
* *
* Paramètres : format = ensemble d'instructions désassemblées. *
-* iter = itérateur sur les symboles à parcourir. *
+* start = point de départ du parcours de la PLT. *
* str_start = début de la zone contenant les descriptions. *
* relocs = table des relocalisations chargées. *
* rel_count = nombre de ces éléments à interpréter. *
@@ -353,7 +361,7 @@ GElfLoading *g_elf_loading_new_for_relocations(GElfFormat *format, phys_t begin,
* *
******************************************************************************/
-GElfLoading *g_elf_loading_new_for_applying(GElfFormat *format, sym_iter_t *iter, phys_t str_start, elf_rel *relocs, size_t rel_count, phys_t sym_start, uint32_t sym_count, activity_id_t id, elf_applying_cb callback)
+GElfLoading *g_elf_loading_new_for_imported(GElfFormat *format, const vmpa2t *start, phys_t str_start, elf_rel *relocs, size_t rel_count, phys_t sym_start, uint32_t sym_count, activity_id_t id, elf_importing_cb callback)
{
GElfLoading *result; /* Tâche à retourner */
@@ -368,7 +376,9 @@ GElfLoading *g_elf_loading_new_for_applying(GElfFormat *format, sym_iter_t *iter
result->sym_start = sym_start;
result->sym_count = sym_count;
- result->iter = iter;
+ result->imports_to_fill = calloc(rel_count, sizeof(GBinSymbol *));
+
+ copy_vmpa(&result->start, start);
result->callback_1 = callback;
result->kind = 1;
@@ -454,11 +464,10 @@ GElfLoading *g_elf_loading_new_for_strings(GElfFormat *format, phys_t begin, phy
static void g_elf_loading_process(GElfLoading *loading, GtkStatusStack *status)
{
GElfFormat *format; /* Format plus accessible */
- phys_t iter; /* Boucle de parcours */
+ phys_t iter; /* Boucle de parcours #1 */
phys_t old; /* Sauvegarde du point d'avant */
bool ret; /* Bilan d'un appel */
- size_t processed; /* Nombre de symboles traités */
- virt_t valid; /* Adresse virtuelle valide */
+ size_t i; /* Boucle de parcours #2 */
GBinSymbol *symbol; /* Symbole analysé */
format = loading->format;
@@ -487,35 +496,23 @@ static void g_elf_loading_process(GElfLoading *loading, GtkStatusStack *status)
case 1:
- ret = true;
-
- processed = 0;
- valid = 0;
-
- for (symbol = get_symbol_iterator_next(loading->iter);
- symbol != NULL && ret;
- symbol = get_symbol_iterator_next(loading->iter))
+ for (i = 0; i < loading->rel_count; i++)
{
- ret = loading->callback_1(loading, format, &valid, symbol);
-
- g_object_unref(G_OBJECT(symbol));
+ symbol = loading->callback_1(loading, format, &loading->start);
- if (!ret)
+ if (symbol == NULL)
{
- log_variadic_message(LMT_ERROR, _("Error while applying ELF relocation %zu!"), processed);
+ log_variadic_message(LMT_ERROR, _("Error while applying ELF relocation %zu!"), i);
break;
}
- processed++;
+ loading->imports_to_fill[i] = symbol;
gtk_status_stack_update_activity_value(status, loading->id, 1);
- if (processed == loading->rel_count)
- break;
-
}
- loading->status = (processed == loading->rel_count);
+ loading->status = (i == loading->rel_count);
break;
case 2:
@@ -702,25 +699,28 @@ bool g_elf_loading_search_for_relocation(const GElfLoading *loading, const uint6
* Paramètres : loading = chargement pour ELF à poursuivre. *
* index = indice du symbole concerné. *
* *
-* Description : Construit la désignation adaptée à un symbole importé. *
+* Description : Construit le symbole adapté à un symbole importé. *
* *
-* Retour : Nouvelle étiquette constituée ou NULL en cas d'échec. *
+* Retour : Nouveau symbole constitué ou NULL en cas d'échec. *
* *
* Remarques : - *
* *
******************************************************************************/
-char *g_elf_loading_build_plt_name(const GElfLoading *loading, uint64_t index)
+GBinSymbol *g_elf_loading_build_plt_symbol(const GElfLoading *loading, uint64_t index)
{
- char *result; /* Désignation à retourner */
+ GBinSymbol *result; /* Symbole à retourner */
GElfFormat *format; /* Format plus accessible */
phys_t offset; /* Tête de lecture brute */
elf_sym sym; /* Symbole aux infos visées */
bool status; /* Bilan de récupération */
uint32_t name; /* Indice du nom du symbole */
vmpa2t pos; /* Position de lecture */
+ GBinFormat *base; /* Autre version du format */
const GBinContent *content; /* Contenu binaire à lire */
- const char *prefix; /* Première partie de nom */
+ const char *raw_label; /* Première partie de nom */
+ GBinRoutine *routine; /* Routine à mettre en place */
+ char *new_label; /* Nouvelle étiquette */
format = loading->format;
@@ -739,17 +739,27 @@ char *g_elf_loading_build_plt_name(const GElfLoading *loading, uint64_t index)
init_vmpa(&pos, offset, VMPA_NO_VIRTUAL);
- content = G_BIN_FORMAT(format)->content;
+ base = G_BIN_FORMAT(format);
+ content = base->content;
- prefix = (const char *)g_binary_content_get_raw_access(content, &pos, 1);
+ raw_label = (const char *)g_binary_content_get_raw_access(content, &pos, 1);
- if (prefix != NULL && prefix[0] == '\0')
+ if (raw_label != NULL && raw_label[0] == '\0')
result = NULL;
else
{
- result = strdup(prefix);
- result = stradd(result, "@plt");
+ routine = g_binary_format_decode_routine(base, raw_label);
+
+ raw_label = g_binary_routine_get_name(routine);
+
+ new_label = strdup(raw_label);
+ new_label = stradd(new_label, "@plt");
+
+ g_binary_routine_set_name(routine, new_label);
+
+ result = G_BIN_SYMBOL(routine);
+
}
}
@@ -761,6 +771,42 @@ char *g_elf_loading_build_plt_name(const GElfLoading *loading, uint64_t index)
/******************************************************************************
* *
+* Paramètres : loading = chargement pour ELF à poursuivre. *
+* count = taille de la liste retournée. [OUT] *
+* *
+* Description : Fournit la liste de symboles importés constituée. *
+* *
+* Retour : Liste des symboles importés ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinSymbol **g_elf_loading_get_imported_symbols(const GElfLoading *loading, size_t *count)
+{
+ GBinSymbol **result; /* Liste à retourner */
+ size_t i; /* Boucle de parcours */
+
+ *count = loading->rel_count;
+
+ result = malloc(*count * sizeof(GBinSymbol *));
+
+ for (i = 0; i < *count; i++)
+ {
+ result[i] = loading->imports_to_fill[i];
+ assert(result[i] != NULL);
+
+ g_object_ref(G_OBJECT(result[i]));
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : loading = chargement pour ELF à mener. *
* content = gestionnaire de contenu utilisé. [OUT] *
* first = première position traitée par la tâche. [OUT] *