diff options
Diffstat (limited to 'plugins/elf/format.c')
-rw-r--r-- | plugins/elf/format.c | 129 |
1 files changed, 90 insertions, 39 deletions
diff --git a/plugins/elf/format.c b/plugins/elf/format.c index eb22059..0fb2d1e 100644 --- a/plugins/elf/format.c +++ b/plugins/elf/format.c @@ -60,6 +60,12 @@ static void g_elf_format_dispose(GElfFormat *); /* Procède à la libération totale de la mémoire. */ static void g_elf_format_finalize(GElfFormat *); +/* Indique la désignation interne du format. */ +static const char *g_elf_format_get_name(const GElfFormat *); + +/* Assure l'interprétation d'un format en différé. */ +static bool g_elf_format_analyze(GElfFormat *, wgroup_id_t, GtkStatusStack *); + /* Informe quant au boutisme utilisé. */ static SourceEndian g_elf_format_get_endianness(const GElfFormat *); @@ -159,6 +165,8 @@ static void g_elf_format_class_init(GElfFormatClass *klass) fmt = G_BIN_FORMAT_CLASS(klass); + fmt->get_name = (format_get_name_fc)g_elf_format_get_name; + fmt->analyze = (format_analyze_fc)g_elf_format_analyze; fmt->get_endian = (format_get_endian_fc)g_elf_format_get_endianness; fmt->complete = (format_complete_analysis_fc)g_elf_format_complete_analysis; @@ -236,8 +244,6 @@ 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. * * * @@ -247,65 +253,113 @@ static void g_elf_format_finalize(GElfFormat *format) * * ******************************************************************************/ -GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatusStack *status) +GExeFormat *g_elf_format_new(GBinContent *content) { GElfFormat *result; /* Structure à retourner */ - GBinFormat *base; /* Version basique du format */ - GExeFormat *exe_format; /* Autre version du format */ result = g_object_new(G_TYPE_ELF_FORMAT, NULL); - base = G_BIN_FORMAT(result); - exe_format = G_EXE_FORMAT(result); + g_binary_format_set_content(G_BIN_FORMAT(result), content); + + return G_EXE_FORMAT(result); - g_binary_format_set_content(base, content); +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* * +* Description : Indique la désignation interne du format. * +* * +* Retour : Description du format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *g_elf_format_get_name(const GElfFormat *format) +{ + const char *result; /* Désignation à retourner */ + + result = "elf"; + + return result; + +} - if (!read_elf_header(result, &result->header, &result->is_32b, &result->endian)) - goto gefn_error; + +/****************************************************************************** +* * +* Paramètres : format = format chargé dont l'analyse est lancée. * +* gid = groupe de travail dédié. * +* status = barre de statut à tenir informée. * +* * +* Description : Assure l'interprétation d'un format en différé. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_elf_format_analyze(GElfFormat *format, wgroup_id_t gid, GtkStatusStack *status) +{ + bool result; /* Bilan à retourner */ + GBinFormat *base; /* Version basique du format */ + GExeFormat *exe; /* Autre version du format */ + + result = false; + + base = G_BIN_FORMAT(format); + exe = G_EXE_FORMAT(format); + + if (!read_elf_header(format, &format->header, &format->is_32b, &format->endian)) + goto gefa_error; /* Vérification des tailles d'entrée de table */ - if (ELF_HDR(result, result->header, e_phentsize) != ELF_SIZEOF_PHDR(result)) + if (ELF_HDR(format, format->header, e_phentsize) != ELF_SIZEOF_PHDR(format)) { log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed!" \ " -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), - ELF_HDR(result, result->header, e_phentsize), - ELF_HDR(result, result->header, e_phentsize), - ELF_SIZEOF_PHDR(result), - ELF_HDR_OFFSET_OF(result, e_phentsize)); + ELF_HDR(format, format->header, e_phentsize), + ELF_HDR(format, format->header, e_phentsize), + ELF_SIZEOF_PHDR(format), + ELF_HDR_OFFSET_OF(format, e_phentsize)); - ELF_HDR_SET(result, result->header, e_phentsize, ELF_SIZEOF_PHDR(result)); + ELF_HDR_SET(format, format->header, e_phentsize, ELF_SIZEOF_PHDR(format)); } - if (ELF_HDR(result, result->header, e_shentsize) != ELF_SIZEOF_SHDR(result)) + if (ELF_HDR(format, format->header, e_shentsize) != ELF_SIZEOF_SHDR(format)) { log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed!" \ " -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), - ELF_HDR(result, result->header, e_shentsize), - ELF_HDR(result, result->header, e_shentsize), - ELF_SIZEOF_SHDR(result), - ELF_HDR_OFFSET_OF(result, e_shentsize)); + ELF_HDR(format, format->header, e_shentsize), + ELF_HDR(format, format->header, e_shentsize), + ELF_SIZEOF_SHDR(format), + ELF_HDR_OFFSET_OF(format, e_shentsize)); - ELF_HDR_SET(result, result->header, e_shentsize, ELF_SIZEOF_SHDR(result)); + ELF_HDR_SET(format, format->header, e_shentsize, ELF_SIZEOF_SHDR(format)); } /* Opérations spécifiques à l'architecture */ - switch (ELF_HDR(result, result->header, e_machine)) + switch (ELF_HDR(format, format->header, e_machine)) { case EM_ARM: - result->ops.get_type_desc = (get_elf_prgm_type_desc_cb)get_elf_program_arm_type_desc; - result->ops.fix_virt = (fix_elf_virt_addr_cb)fix_elf_arm_virtual_address; - result->ops.get_linkage_offset = (get_elf_linkage_offset_cb)retrieve_arm_linkage_offset; + format->ops.get_type_desc = (get_elf_prgm_type_desc_cb)get_elf_program_arm_type_desc; + format->ops.fix_virt = (fix_elf_virt_addr_cb)fix_elf_arm_virtual_address; + format->ops.get_linkage_offset = (get_elf_linkage_offset_cb)retrieve_arm_linkage_offset; break; default: log_variadic_message(LMT_ERROR, "Architecture not supported for ELF binaries"); - goto gefn_error; + goto gefa_error; break; } @@ -323,23 +377,20 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatus preload_binary_format(PGA_FORMAT_PRELOAD, base, base->info, status); + if (!load_elf_symbols(format, status)) + goto gefa_error; - if (!load_elf_symbols(result, status)) - goto gefn_error; + if (!find_all_elf_strings(format)) + goto gefa_error; - if (!find_all_elf_strings(result)) - goto gefn_error; + if (!g_executable_format_complete_loading(exe, status)) + goto gefa_error; - if (!g_executable_format_complete_loading(exe_format, status)) - goto gefn_error; + result = true; - return base; + gefa_error: - gefn_error: - - g_object_unref(G_OBJECT(result)); - - return NULL; + return result; } |