diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | plugins/elf/elf-int.h | 23 | ||||
-rw-r--r-- | plugins/elf/format.c | 20 | ||||
-rw-r--r-- | plugins/elf/helper_arm.c | 23 | ||||
-rw-r--r-- | plugins/elf/helper_arm.h | 3 | ||||
-rw-r--r-- | plugins/elf/program.c | 16 | ||||
-rw-r--r-- | plugins/elf/symbols.c | 15 |
7 files changed, 87 insertions, 27 deletions
@@ -1,5 +1,19 @@ 18-01-29 Cyrille Bagard <nocbos@gmail.com> + * plugins/elf/elf-int.h: + * plugins/elf/format.c: + Introduce specific operations for ELF architectures. + + * plugins/elf/helper_arm.c: + * plugins/elf/helper_arm.h: + Fix virtual addresses for the Thumb mode. + + * plugins/elf/program.c: + * plugins/elf/symbols.c: + Update code. + +18-01-29 Cyrille Bagard <nocbos@gmail.com> + * plugins/elf/dynamic.c: * plugins/elf/dynamic.h: Extract more information from the PT_DYNAMIC segment. diff --git a/plugins/elf/elf-int.h b/plugins/elf/elf-int.h index 3b4b67c..291000d 100644 --- a/plugins/elf/elf-int.h +++ b/plugins/elf/elf-int.h @@ -34,6 +34,27 @@ +/* Fournit la description humaine d'un type de segment ELF. */ +typedef const char * (* get_elf_prgm_type_desc_cb) (uint32_t); + +/* Fournit une adresse virtuelle prête à emploi. */ +typedef virt_t (* fix_elf_virt_addr_cb) (virt_t); + +/* Retrouve le décalage appliqué lors d'une résolution. */ +typedef bool (* get_elf_linkage_offset_cb) (GElfFormat *, const mrange_t *, uint64_t *); + + + +/* Particularités propre aux architectures */ +typedef struct _elf_arch_ops +{ + get_elf_prgm_type_desc_cb get_type_desc;/* Description de type */ + fix_elf_virt_addr_cb fix_virt; /* Retire toute forme d'infos */ + get_elf_linkage_offset_cb get_linkage_offset; /* Décalage de relocation*/ + +} elf_arch_ops; + + /* Format d'exécutable générique (instance) */ struct _GElfFormat { @@ -43,6 +64,8 @@ struct _GElfFormat bool is_32b; /* Format du binaire */ SourceEndian endian; /* Boutisme du format */ + elf_arch_ops ops; /* Opérations spécifiques */ + }; /* Format d'exécutable générique (classe) */ diff --git a/plugins/elf/format.c b/plugins/elf/format.c index d48eef9..755bc12 100644 --- a/plugins/elf/format.c +++ b/plugins/elf/format.c @@ -36,6 +36,7 @@ #include "elf-int.h" +#include "helper_arm.h" #include "program.h" #include "section.h" #include "strings.h" @@ -292,6 +293,25 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatus } + /* Opérations spécifiques à l'architecture */ + + switch (ELF_HDR(result, result->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; + break; + + default: + log_variadic_message(LMT_ERROR, "Architecture not supported for ELF binaries"); + goto gefn_error; + break; + + } + + /* Chargements des informations utiles */ + /** * On inscrit les éléments préchargés avant tout ! * diff --git a/plugins/elf/helper_arm.c b/plugins/elf/helper_arm.c index 4c34d78..51bdb99 100644 --- a/plugins/elf/helper_arm.c +++ b/plugins/elf/helper_arm.c @@ -63,6 +63,29 @@ const char *get_elf_program_arm_type_desc(uint32_t p_type) /****************************************************************************** * * +* Paramètres : virt = adresse virtuelle éventuellement porteuse d'infos. * +* * +* Description : Fournit une adresse virtuelle prête à emploi. * +* * +* Retour : Adresse virtuelle réellement utilisable. * +* * +* Remarques : - * +* * +******************************************************************************/ + +virt_t fix_elf_arm_virtual_address(virt_t virt) +{ + virt_t result; /* Résultat à retourner */ + + result = virt & ~0x1; + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : format = description de l'exécutable à manipuler. * * range = emplacement de la procédure de liaison. * * offset = décalage retrouvé par désassemblage... [OUT] * diff --git a/plugins/elf/helper_arm.h b/plugins/elf/helper_arm.h index 07549ad..3db9324 100644 --- a/plugins/elf/helper_arm.h +++ b/plugins/elf/helper_arm.h @@ -32,6 +32,9 @@ /* Fournit la description humaine d'un type de segment ELF. */ const char *get_elf_program_arm_type_desc(uint32_t); +/* Fournit une adresse virtuelle prête à emploi. */ +virt_t fix_elf_arm_virtual_address(virt_t); + /* Retrouve le décalage appliqué lors d'une résolution. */ bool retrieve_arm_linkage_offset(GElfFormat *, const mrange_t *, uint64_t *); diff --git a/plugins/elf/program.c b/plugins/elf/program.c index 7e6f2e4..83fdc6f 100644 --- a/plugins/elf/program.c +++ b/plugins/elf/program.c @@ -25,7 +25,6 @@ #include "elf-int.h" -#include "helper_arm.h" @@ -59,15 +58,11 @@ const char *get_elf_program_type_desc(const GElfFormat *format, uint32_t p_type) MAKE_STRING_FROM_PT(PT_PHDR); MAKE_STRING_FROM_PT(PT_TLS); MAKE_STRING_FROM_PT(PT_NUM); - MAKE_STRING_FROM_PT(PT_LOOS); MAKE_STRING_FROM_PT(PT_GNU_EH_FRAME); MAKE_STRING_FROM_PT(PT_GNU_STACK); MAKE_STRING_FROM_PT(PT_GNU_RELRO); MAKE_STRING_FROM_PT(PT_LOSUNW); MAKE_STRING_FROM_PT(PT_SUNWSTACK); - MAKE_STRING_FROM_PT(PT_HIOS); - MAKE_STRING_FROM_PT(PT_LOPROC); - MAKE_STRING_FROM_PT(PT_HIPROC); default: result = NULL; @@ -76,16 +71,7 @@ const char *get_elf_program_type_desc(const GElfFormat *format, uint32_t p_type) } if (result == NULL) - switch (ELF_HDR(format, format->header, e_machine)) - { - case EM_ARM: - result = get_elf_program_arm_type_desc(p_type); - break; - - default: - break; - - } + result = format->ops.get_type_desc(p_type); if (result == NULL) switch(p_type) diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c index 4854d7b..dbf3305 100644 --- a/plugins/elf/symbols.c +++ b/plugins/elf/symbols.c @@ -42,7 +42,6 @@ #include "dynamic.h" #include "elf-int.h" -#include "helper_arm.h" #include "loading.h" #include "program.h" #include "section.h" @@ -189,10 +188,7 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le /* Localisation complète du symbole */ - if (ELF_HDR(format, format->header, e_machine) == EM_ARM) - final_vaddr = vaddr & ~0x1; - else - final_vaddr = vaddr; + final_vaddr = format->ops.fix_virt(vaddr); status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_vaddr, &addr); if (!status) return; @@ -514,8 +510,7 @@ static bool do_elf_symbol_loading(GElfLoading *loading, GElfFormat *format, bool /* Ajustement de la position */ - if (ELF_HDR(format, format->header, e_machine) == EM_ARM) - virt &= ~0x1; + virt = format->ops.fix_virt(virt); /* Constitution d'une routine */ @@ -1205,11 +1200,7 @@ static bool do_elf_relocation_renaming(GElfLoading *loading, GElfFormat *format, /* Détermination de la relocalisation associée */ - if (ELF_HDR(format, format->header, e_machine) == EM_ARM) - result = retrieve_arm_linkage_offset(format, range, &offset); - else - result = false; - + result = format->ops.get_linkage_offset(format, range, &offset); if (!result) goto derr_exit; result = g_elf_loading_search_for_relocation(loading, &offset, &reloc); |