diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-04-26 10:34:20 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-04-26 10:34:20 (GMT) |
commit | 60f7839e36d0eaf5bcc90ffe1369dae56ed53dbe (patch) | |
tree | 752ad498b9704951eb1912f77ab42c6b5ac9f475 /src/format | |
parent | ee0ff01247738e847ae3faa44dcb5168d7b758ba (diff) |
Loaded internal smybols ; created entry points only when needed.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@520 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format')
-rw-r--r-- | src/format/elf/symbols.c | 103 | ||||
-rw-r--r-- | src/format/format.c | 140 | ||||
-rw-r--r-- | src/format/format.h | 6 |
3 files changed, 203 insertions, 46 deletions
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index b57c601..4c1811f 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -93,7 +93,7 @@ static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *); -#include <stdlib.h> + /****************************************************************************** * * @@ -116,18 +116,10 @@ bool load_elf_symbols(GElfFormat *format) result = true; + /* Symboles internes */ + result &= load_elf_internal_symbols(format); - result &= load_all_elf_basic_entry_points(format); - - - - - - /* Symboles internes */ -#if 0 - result = load_elf_internal_symbols(format); -#endif @@ -149,34 +141,9 @@ bool load_elf_symbols(GElfFormat *format) - qsort(G_BIN_FORMAT(format)->symbols, G_BIN_FORMAT(format)->symbols_count, - sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp); + /* Symboles d'entrée, si encore besoin */ -#if 0 - - const vmpa2t *saddr; /* Adresse de symbole */ - size_t i; /* Boucle de parcours #2 */ - GBinSymbol **symbols; /* Symboles à représenter */ - - symbols = G_BIN_FORMAT(format)->symbols; - - for (i = 0; i < G_BIN_FORMAT(format)->symbols_count; i++) - { - saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[i])); - if (saddr == NULL) continue; - - //if (g_binary_symbol_to_string(symbols[i]) == NULL) continue; - - printf(" <symbol % 2zu> '% 22s'-> 0x%08lx 0x%08lx\n", - i, - g_binary_symbol_to_string(symbols[i]), - saddr->physical, - saddr->virtual); - - } - - //exit(0); -#endif + result &= load_all_elf_basic_entry_points(format); return result; @@ -220,13 +187,31 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le init_vmpa(&addr, VMPA_NO_PHYSICAL, vaddr); - init_mrange(&range, &addr, len); + if (g_binary_format_find_symbol_at(format, &addr, &symbol)) + { + g_object_unref(G_OBJECT(routine)); + + routine = g_binary_symbol_get_routine(symbol); + g_object_ref(G_OBJECT(routine)); + + printf(" -- SYM CHANGE @ 0x%08x\n", vaddr); - g_binary_routine_set_range(routine, &range); + _g_binary_symbol_attach_routine(symbol, routine, STP_ENTRY_POINT); + + } + else + { + printf(" -- SYM ENTRY @ 0x%08x\n", vaddr); - symbol = g_binary_symbol_new(STP_ENTRY_POINT, "XXX", ~0); - g_binary_symbol_attach_routine(symbol, routine); - g_binary_format_add_symbol(base, symbol); + init_mrange(&range, &addr, len); + + g_binary_routine_set_range(routine, &range); + + symbol = g_binary_symbol_new(STP_ENTRY_POINT, "XXX", ~0); + g_binary_symbol_attach_routine(symbol, routine); + g_binary_format_add_symbol(base, symbol); + + } } @@ -530,6 +515,7 @@ static bool load_elf_internal_symbols(GElfFormat *format) off_t size; /* Taille de cette même zone */ off_t iter; /* Boucle de parcours */ elf_sym sym; /* Symbole aux infos visées */ + virt_t virt; /* Adresse virtuelle */ vmpa2t addr; /* Localisation d'une routine */ mrange_t range; /* Couverture mémoire associée */ const char *name; /* Nom du symbole trouvé */ @@ -546,6 +532,21 @@ static bool load_elf_internal_symbols(GElfFormat *format) 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; + +#if 0 + + 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 + + if (ELF_SYM(format, sym, st_value) == 0) continue; /* Résolution précise d'adresse */ @@ -553,10 +554,20 @@ static bool load_elf_internal_symbols(GElfFormat *format) /* TODO */ - init_vmpa(&addr, ELF_SYM(format, sym, st_value), VMPA_NO_VIRTUAL); + //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value)); + + virt = ELF_SYM(format, sym, st_value); + + if (ELF_HDR(format, format->header, e_machine) == EM_ARM) + virt &= ~0x1; + + if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr)) + continue; + - init_mrange(&range, &addr, ELF_SYM(format, sym, st_size)); + //init_mrange(&range, &addr, ELF_SYM(format, sym, st_size)); + init_mrange(&range, &addr, 0); /* Première ébauche de nom */ @@ -609,7 +620,7 @@ static bool load_elf_internal_symbols(GElfFormat *format) /* Routine */ - printf("ADDING>> '%s'\n", name); + printf("SYM ADDING>> '%s'\n", name); routine = try_to_demangle_routine(name); diff --git a/src/format/format.c b/src/format/format.c index 5478d3c..2256160 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -49,6 +49,9 @@ static void g_binary_format_class_init(GBinFormatClass *); /* Initialise une instance de format binaire générique. */ static void g_binary_format_init(GBinFormat *); +/* Retire un symbole de la collection du format binaire. */ +static void _g_binary_format_remove_symbol(GBinFormat *, size_t); + /* Indique le type défini pour un format binaire générique. */ @@ -222,6 +225,96 @@ void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol) /****************************************************************************** * * +* Paramètres : format = informations chargées à compléter. * +* index = indice du symbole à retirer de la liste. * +* * +* Description : Retire un symbole de la collection du format binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _g_binary_format_remove_symbol(GBinFormat *format, size_t index) +{ + GBinSymbol *symbol; /* Symbole visé par l'opération*/ + GBinRoutine *routine; /* Eventuelle routine associée */ + size_t i; /* Boucle de parcours */ + + /** + * TODO : envoyer un signal pour avertir les opérandes concernées. + */ + + symbol = format->symbols[index]; + + switch (g_binary_symbol_get_target_type(symbol)) + { + case STP_ROUTINE: + case STP_ENTRY_POINT: + + routine = g_binary_symbol_get_routine(symbol); + + for (i = 0; i < format->routines_count; i++) + if (format->routines[i] == routine) + break; + + assert(i < format->routines_count); + + if ((i + 1) < format->routines_count) + memmove(&format->routines[i], &format->routines[i + 1], + (format->routines_count - i - 1) * sizeof(GBinRoutine *)); + + format->routines = (GBinRoutine **)realloc(format->routines, + --format->routines_count * sizeof(GBinRoutine *)); + + break; + + default: + break; + + } + + assert(index < format->symbols_count); + + if ((index + 1) < format->symbols_count) + memmove(&format->symbols[index], &format->symbols[index + 1], + (format->symbols_count - index - 1) * sizeof(GBinSymbol *)); + + format->symbols = (GBinSymbol **)realloc(format->symbols, + --format->symbols_count * sizeof(GBinSymbol *)); + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à compléter. * +* symbol = symbole à retirer de la liste. * +* * +* Description : Retire un symbole de la collection du format binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_format_remove_symbol(GBinFormat *format, GBinSymbol *symbol) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < format->symbols_count; i++) + if (format->symbols[i] == symbol) + break; + + _g_binary_format_remove_symbol(format, i); + +} + + +/****************************************************************************** +* * * Paramètres : format = informations chargées à consulter. * * count = taille du tableau créé. [OUT] * * * @@ -480,6 +573,53 @@ void g_binary_format_add_routine(GBinFormat *format, GBinRoutine *routine) /****************************************************************************** * * +* Paramètres : format = informations chargées à compléter. * +* routine = routine à ajouter à la liste. * +* * +* Description : Retire une routine de la collection du format binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_format_remove_routine(GBinFormat *format, GBinRoutine *routine) +{ + size_t index; /* Indice trouvé à utiliser */ + size_t i; /* Boucle de parcours */ + GBinSymbol *symbol; /* Symbole en cours d'analyse */ + + index = format->symbols_count; + + for (i = 0; i < format->symbols_count && index == format->symbols_count; i++) + { + symbol = format->symbols[i]; + + switch (g_binary_symbol_get_target_type(symbol)) + { + case STP_ROUTINE: + case STP_ENTRY_POINT: + + if (g_binary_symbol_get_routine(symbol) == routine) + index = i; + + break; + + default: + break; + + } + + } + + _g_binary_format_remove_symbol(format, index); + +} + + +/****************************************************************************** +* * * Paramètres : format = informations chargées à consulter. * * count = taille du tableau créé. [OUT] * * * diff --git a/src/format/format.h b/src/format/format.h index 38418b3..66f014b 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -67,6 +67,9 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *, GProcContex /* Ajoute un symbole à la collection du format binaire. */ void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *); +/* Retire un symbole de la collection du format binaire. */ +void g_binary_format_remove_symbol(GBinFormat *, GBinSymbol *); + /* Fournit la liste de tous les symboles détectés. */ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *); @@ -85,6 +88,9 @@ bool g_binary_format_resolve_symbol(const GBinFormat *, const vmpa2t *, GBinSymb /* Ajoute une routine à la collection du format binaire. */ void g_binary_format_add_routine(GBinFormat *, GBinRoutine *) __attribute__ ((deprecated)); +/* Retire une routine de la collection du format binaire. */ +void g_binary_format_remove_routine(GBinFormat *, GBinRoutine *); + /* Fournit le prototype de toutes les routines détectées. */ GBinRoutine **g_binary_format_get_routines(const GBinFormat *, size_t *); |